diff options
Diffstat (limited to 'shared')
166 files changed, 0 insertions, 41289 deletions
diff --git a/shared/FindFilePlus/FindFilePlus.vcxproj b/shared/FindFilePlus/FindFilePlus.vcxproj deleted file mode 100644 index a49e99ba..00000000 --- a/shared/FindFilePlus/FindFilePlus.vcxproj +++ /dev/null @@ -1,245 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">FindFilePlus_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">FindFilePlus_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">FindFilePlus_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">FindFilePlus_$(Platform)</TargetName> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_X86_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <AdditionalIncludeDirectories>C:\Program Files\C++\Projects\FreeFileSync\shared</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_AMD64_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <AdditionalIncludeDirectories>C:\Program Files\C++\Projects\FreeFileSync\shared</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_X86_;NDEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <AdditionalIncludeDirectories>C:\Program Files\C++\Projects\FreeFileSync\shared</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <AdditionalIncludeDirectories>C:\Program Files\C++\Projects\FreeFileSync\shared</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="find_file_plus.cpp" /> - <ClCompile Include="load_dll.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="find_file_plus.h" /> - <ClInclude Include="load_dll.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/FindFilePlus/dll_main.cpp b/shared/FindFilePlus/dll_main.cpp deleted file mode 100644 index 3805c99d..00000000 --- a/shared/FindFilePlus/dll_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -//optional: add init/teardown logic here -BOOL APIENTRY DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - case DLL_PROCESS_DETACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - } - return TRUE; -} diff --git a/shared/FindFilePlus/find_file_plus.cpp b/shared/FindFilePlus/find_file_plus.cpp deleted file mode 100644 index 8b29efa2..00000000 --- a/shared/FindFilePlus/find_file_plus.cpp +++ /dev/null @@ -1,305 +0,0 @@ -// ************************************************************************** -// * 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 "find_file_plus.h" -//#include <windows.h> //these two don't play nice with each other - -#include "load_dll.h" -#include <loki/ScopeGuard.h> - -using namespace dll; -using namespace findplus; - - -namespace -{ -//-------------------------------------------------------------------------------------------------------------- -typedef NTSTATUS (NTAPI* NtOpenFileFunc)(PHANDLE fileHandle, - ACCESS_MASK desiredAccess, - POBJECT_ATTRIBUTES objectAttributes, - PIO_STATUS_BLOCK ioStatusBlock, - ULONG shareAccess, - ULONG openOptions); - -typedef NTSTATUS (NTAPI* NtCloseFunc)(HANDLE handle); - -typedef NTSTATUS (NTAPI* NtQueryDirectoryFileFunc)(HANDLE fileHandle, - HANDLE event, - PIO_APC_ROUTINE apcRoutine, - PVOID apcContext, - PIO_STATUS_BLOCK ioStatusBlock, - PVOID fileInformation, - ULONG length, - FILE_INFORMATION_CLASS fileInformationClass, - BOOLEAN ReturnSingleEntry, - PUNICODE_STRING fileMask, - BOOLEAN restartScan); - -typedef ULONG (NTAPI* RtlNtStatusToDosErrorFunc)(NTSTATUS /*__in status*/); - -typedef struct _RTL_RELATIVE_NAME_U -{ - UNICODE_STRING RelativeName; - HANDLE ContainingDirectory; - PVOID /*PRTLP_CURDIR_REF*/ CurDirRef; -} RTL_RELATIVE_NAME_U, *PRTL_RELATIVE_NAME_U; - -typedef BOOLEAN (NTAPI* RtlDosPathNameToNtPathName_UFunc)(PCWSTR, //__in dosFileName, - PUNICODE_STRING, //__out ntFileName, - PCWSTR*, //__out_optFilePart, - PRTL_RELATIVE_NAME_U); //__out_opt relativeName - -typedef BOOLEAN (NTAPI* RtlDosPathNameToRelativeNtPathName_UFunc)(PCWSTR, //__in dosFileName, - PUNICODE_STRING, //__out ntFileName, - PWSTR*, //__out_optFilePart, - PRTL_RELATIVE_NAME_U); //__out_opt relativeName - -typedef VOID (NTAPI* RtlFreeUnicodeStringFunc)(PUNICODE_STRING); //__inout unicodeString - -//-------------------------------------------------------------------------------------------------------------- - -//it seems we cannot use any of the ntoskrnl.lib files in WinDDK as they produce access violations -//fortunately dynamic binding works fine: -NtOpenFileFunc ntOpenFile; -NtCloseFunc ntClose; -NtQueryDirectoryFileFunc ntQueryDirectoryFile; -RtlNtStatusToDosErrorFunc rtlNtStatusToDosError; -RtlFreeUnicodeStringFunc rtlFreeUnicodeString; -RtlDosPathNameToNtPathName_UFunc rtlDosPathNameToNtPathName_U; - - -template <class FunType> inline -void initDllFun(FunType& fun, const char* functionName) //throw FileError -{ - if (!fun) - { - fun = getSystemDllFun<FunType>(L"ntdll.dll", functionName); - if (!fun) - throw FileError(182); //== ERROR_INVALID_ORDINAL, verified at compile time in "load_dll.cpp"; we better not use rtlNtStatusToDosError(STATUS_ORDINAL_NOT_FOUND) here ;) - } -} - - -struct FileError -{ - FileError(ULONG errorCode) : win32Error(errorCode) {} - ULONG win32Error; -}; -} - -class findplus::FileSearcher -{ -public: - FileSearcher(const wchar_t* dirname); //throw FileError - ~FileSearcher(); - - void readdir(FileInformation& output); //throw FileError - -private: - UNICODE_STRING ntPathName; //it seems hDir implicitly keeps a reference to this, at least ::FindFirstFile() does no cleanup before ::FindClose()! - HANDLE hDir; - - ULONG nextEntryOffset; //!= 0 if entry is waiting in buffer - //::FindNextFileW() uses 0x1000 = 4096 = sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * 2000 - //=> let's use the same, even if our header is 16 byte larger; maybe there is some packet size advantage for networks? Note that larger buffers seem to degrade performance. - static const ULONG BUFFER_SIZE = 4096; - LONGLONG buffer[BUFFER_SIZE / sizeof(LONGLONG)]; //buffer needs to be aligned at LONGLONG boundary - - static_assert(BUFFER_SIZE % sizeof(LONGLONG) == 0, "ups, our buffer is trimmed!"); -}; - - -FileSearcher::FileSearcher(const wchar_t* dirname) : - hDir(NULL), - nextEntryOffset(0) -{ - UNICODE_STRING cleanDummy = {}; - ntPathName = cleanDummy; - - Loki::ScopeGuard guardConstructor = Loki::MakeGuard([&]() { this->~FileSearcher(); }); - - //NT/ZwXxx Routines - //http://msdn.microsoft.com/en-us/library/ff567122(v=VS.85).aspx - - //Run-Time Library (RTL) Routines - //http://msdn.microsoft.com/en-us/library/ff563638(v=VS.85).aspx - - //init static dll functions - initDllFun(ntOpenFile, "NtOpenFile"); //throw FileError - initDllFun(ntClose, "NtClose"); - initDllFun(ntQueryDirectoryFile, "NtQueryDirectoryFile"); - initDllFun(rtlNtStatusToDosError, "RtlNtStatusToDosError"); - initDllFun(rtlFreeUnicodeString, "RtlFreeUnicodeString"); - try - { - initDllFun(rtlDosPathNameToNtPathName_U, "RtlDosPathNameToRelativeNtPathName_U"); //use the newer version if available - } - catch (const FileError&) - { - initDllFun(rtlDosPathNameToNtPathName_U, "RtlDosPathNameToNtPathName_U"); //fallback for XP - } - //-------------------------------------------------------------------------------------------------------------- - - //convert dosFileName, e.g. C:\Users or \\?\C:\Users to ntFileName \??\C:\Users - //in contrast to ::FindFirstFile() we don't evaluate the relativeName, however tests indicate ntFileName is *always* filled with an absolute name, even if dosFileName is relative - - //NOTE: RtlDosPathNameToNtPathName_U may be used on all XP/Win7/Win8 for compatibility - // RtlDosPathNameToNtPathName_U: used by Windows XP available with OS version 3.51 (Windows NT) and higher - // RtlDosPathNameToRelativeNtPathName_U: used by Win7/Win8 available with OS version 5.2 (Windows Server 2003) and higher - if (!rtlDosPathNameToNtPathName_U(dirname, //__in dosFileName, - &ntPathName, //__out ntFileName, - NULL, //__out_optFilePart, - NULL)) //__out_opt relativeName - empty if dosFileName is absolute - throw FileError(rtlNtStatusToDosError(STATUS_OBJECT_PATH_NOT_FOUND)); //translates to ERROR_PATH_NOT_FOUND, same behavior like ::FindFirstFileEx() - - OBJECT_ATTRIBUTES objAttr = {}; - InitializeObjectAttributes(&objAttr, //[out] POBJECT_ATTRIBUTES initializedAttributes, - &ntPathName, //[in] PUNICODE_STRING objectName, - OBJ_CASE_INSENSITIVE, //[in] ULONG attributes, - NULL, //[in] HANDLE rootDirectory, - NULL); //[in, optional] PSECURITY_DESCRIPTOR securityDescriptor - - { - IO_STATUS_BLOCK status = {}; - NTSTATUS rv = ntOpenFile(&hDir, //__out PHANDLE FileHandle, - FILE_LIST_DIRECTORY | SYNCHRONIZE, //__in ACCESS_MASK desiredAccess, - 100001 used by ::FindFirstFile() on all XP/Win7/Win8 - &objAttr, //__in POBJECT_ATTRIBUTES objectAttributes, - &status, //__out PIO_STATUS_BLOCK ioStatusBlock, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //__in ULONG shareAccess, - 7 on Win7/Win8, 3 on XP - FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); //__in ULONG openOptions - 4021 used on all XP/Win7/Win8 - if (!NT_SUCCESS(rv)) - throw FileError(rtlNtStatusToDosError(rv)); - } - - guardConstructor.Dismiss(); -} - - -FileSearcher::~FileSearcher() -{ - //cleanup in reverse order - if (hDir) - ntClose(hDir); - - if (ntPathName.Buffer) - rtlFreeUnicodeString(&ntPathName); //cleanup identical to ::FindFirstFile() - //note that most if this function seems inlined by the linker, so that its assembly looks equivalent to "RtlFreeHeap(GetProcessHeap(), 0, ntPathName.Buffer)" -} - - -void FileSearcher::readdir(FileInformation& output) -{ - //although FILE_ID_FULL_DIR_INFORMATION should suffice for our purposes, there are problems on Windows XP for certain directories, e.g. "\\Vboxsvr\build" - //making NtQueryDirectoryFile() return with STATUS_INVALID_PARAMETER while other directories, e.g. "C:\" work fine for some reason - //FILE_ID_BOTH_DIR_INFORMATION on the other hand works on XP/Win7/Win8 - //performance: there is no noticable difference between FILE_ID_BOTH_DIR_INFORMATION and FILE_ID_FULL_DIR_INFORMATION - - /* corresponding first access in ::FindFirstFileW() - - NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle, - NULL, //__in_opt HANDLE event, - NULL, //__in_opt PIO_APC_ROUTINE apcRoutine, - NULL, //__in_opt PVOID apcContext, - &status, //__out PIO_STATUS_BLOCK ioStatusBlock, - &buffer, //__out_bcount(Length) PVOID fileInformation, - BUFFER_SIZE, //__in ULONG length, ::FindFirstFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * MAX_PATH == 0x268 - FileIdBothDirectoryInformation, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation" - true, //__in BOOLEAN returnSingleEntry, - NULL, //__in_opt PUNICODE_STRING mask, - false); //__in BOOLEAN restartScan - */ - - //analog to ::FindNextFileW() with performance optimized access (in contrast to first access in ::FindFirstFileW()) - if (nextEntryOffset == 0) - { - IO_STATUS_BLOCK status = {}; - NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle, - NULL, //__in_opt HANDLE event, - NULL, //__in_opt PIO_APC_ROUTINE apcRoutine, - NULL, //__in_opt PVOID apcContext, - &status, //__out PIO_STATUS_BLOCK ioStatusBlock, - &buffer, //__out_bcount(Length) PVOID fileInformation, - BUFFER_SIZE, //__in ULONG length, ::FindNextFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * 2000 == 0x1000 - FileIdBothDirectoryInformation, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation" - false, //__in BOOLEAN returnSingleEntry, - NULL, //__in_opt PUNICODE_STRING mask, - false); //__in BOOLEAN restartScan - if (!NT_SUCCESS(rv)) - throw FileError(rtlNtStatusToDosError(rv)); //throws STATUS_NO_MORE_FILES when finished - - if (status.Information == 0) //except for the first call to call ::NtQueryDirectoryFile(): - throw FileError(rtlNtStatusToDosError(STATUS_BUFFER_OVERFLOW)); //if buffer size is too small, return value is STATUS_SUCCESS and Information == 0 -> we don't expect this! - } - - const FILE_ID_BOTH_DIR_INFORMATION& dirInfo = *reinterpret_cast<FILE_ID_BOTH_DIR_INFORMATION*>(reinterpret_cast<char*>(buffer) + nextEntryOffset); - - if (dirInfo.NextEntryOffset == 0) - nextEntryOffset = 0; //our offset is relative to the beginning of the buffer - else - nextEntryOffset += dirInfo.NextEntryOffset; - - - auto toFileTime = [](const LARGE_INTEGER & rawTime) -> FILETIME - { - FILETIME tmp = { rawTime.LowPart, rawTime.HighPart }; - return tmp; - }; - - output.creationTime = toFileTime(dirInfo.CreationTime); - output.lastWriteTime = toFileTime(dirInfo.LastWriteTime); - output.fileSize.QuadPart = dirInfo.EndOfFile.QuadPart; - output.fileId.QuadPart = dirInfo.FileId.QuadPart; - output.fileAttributes = dirInfo.FileAttributes; - output.shortNameLength = dirInfo.FileNameLength / sizeof(TCHAR); //FileNameLength is in bytes! - - if (dirInfo.FileNameLength + sizeof(TCHAR) > sizeof(output.shortName)) //this may actually happen if ::NtQueryDirectoryFile() decides to return a - throw FileError(rtlNtStatusToDosError(STATUS_BUFFER_OVERFLOW)); //short name of length MAX_PATH + 1, 0-termination is not required! - - ::memcpy(output.shortName, dirInfo.FileName, dirInfo.FileNameLength); - output.shortName[output.shortNameLength] = 0; //NOTE: FILE_ID_BOTH_DIR_INFORMATION::FileName in general is NOT 0-terminated! It is on XP/Win7, but NOT on Win8! - - static_assert(sizeof(output.creationTime) == sizeof(dirInfo.CreationTime), "dang!"); - static_assert(sizeof(output.lastWriteTime) == sizeof(dirInfo.LastWriteTime), "dang!"); - static_assert(sizeof(output.fileSize) == sizeof(dirInfo.EndOfFile), "dang!"); - static_assert(sizeof(output.fileId) == sizeof(dirInfo.FileId), "dang!"); - static_assert(sizeof(output.fileAttributes) == sizeof(dirInfo.FileAttributes), "dang!"); -} - - -FindHandle findplus::openDir(const wchar_t* dirname) -{ - try - { - return new FileSearcher(dirname); //throw FileError - } - catch (const FileError& err) - { - setWin32Error(err.win32Error); - return NULL; - } -} - - -bool findplus::readDir(FindHandle hnd, FileInformation& output) -{ - try - { - hnd->readdir(output); //throw FileError - return true; - } - catch (const FileError& err) - { - setWin32Error(err.win32Error); - return false; - } -} - - -void findplus::closeDir(FindHandle hnd) -{ - if (hnd) //play a little "nice" - delete static_cast<FileSearcher*>(hnd); -} diff --git a/shared/FindFilePlus/find_file_plus.h b/shared/FindFilePlus/find_file_plus.h deleted file mode 100644 index 88cb13af..00000000 --- a/shared/FindFilePlus/find_file_plus.h +++ /dev/null @@ -1,78 +0,0 @@ -// ************************************************************************** -// * 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 FIND_FIRST_FILE_PLUS_HEADER_087483434 -#define FIND_FIRST_FILE_PLUS_HEADER_087483434 - -#ifdef FIND_FILE_PLUS_DLL_EXPORTS -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport) -#else -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport) -#endif - - -#ifdef FIND_FILE_PLUS_DLL_EXPORTS -#include <Ntifs.h> //driver level headers must be included *before* windows api headers! -#endif -#include <windef.h> // -#undef min -#undef max - -#include "../build_info.h" - -namespace findplus -{ -/*-------------- - |declarations| - --------------*/ - -struct FileInformation -{ - FILETIME creationTime; - FILETIME lastWriteTime; - ULARGE_INTEGER fileSize; - ULARGE_INTEGER fileId; - DWORD fileAttributes; - DWORD shortNameLength; - WCHAR shortName[MAX_PATH + 1]; //shortName is 0-terminated -}; - -class FileSearcher; -typedef FileSearcher* FindHandle; - -DLL_FUNCTION_DECLARATION -FindHandle openDir(const wchar_t* dirname); //returns NULL on error, call ::GetLastError(); returns ERROR_INVALID_ORDINAL if ntdll-libraries could not be loaded -//note do NOT place an asterisk at end, e.g. C:\SomeDir\*, as one would do for ::FindFirstFile() - -DLL_FUNCTION_DECLARATION -bool readDir(FindHandle hnd, FileInformation& output); //returns false on error or if there are no more files; ::GetLastError() returns ERROR_NO_MORE_FILES - -DLL_FUNCTION_DECLARATION -void closeDir(FindHandle hnd); - -/*---------- - |typedefs| - ----------*/ -typedef FindHandle (*OpenDirFunc )(const wchar_t* dirname); -typedef bool (*ReadDirFunc )(FindHandle hnd, FileInformation& dirInfo); -typedef void (*CloseDirFunc)(FindHandle hnd); - -/*-------------- - |symbol names| - --------------*/ -//const pointers ensure internal linkage -const char openDirFuncName [] = "openDir"; -const char readDirFuncName [] = "readDir"; -const char closeDirFuncName[] = "closeDir"; - -/*--------------- - |library names| - ---------------*/ -inline const wchar_t* getDllName() { return util::is64BitBuild ? L"FindFilePlus_x64.dll" : L"FindFilePlus_Win32.dll"; } -} - - -#endif //FIND_FIRST_FILE_PLUS_HEADER_087483434 diff --git a/shared/FindFilePlus/load_dll.cpp b/shared/FindFilePlus/load_dll.cpp deleted file mode 100644 index 51ec1f0c..00000000 --- a/shared/FindFilePlus/load_dll.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> // yes, this sequence is mad, but ddk and api headers contain plenty of redefinitions -#include "load_dll.h" // - -void* /*FARPROC*/ dll::loadSymbol(const wchar_t* libraryName, const char* functionName) -{ - return ::GetProcAddress(::GetModuleHandle(libraryName), functionName); - //cleanup neither required nor allowed (::FreeLibrary()) - -} -//note: void* and FARPROC function pointer have same binary size on Windows - - -void dll::setWin32Error(unsigned long lastError) -{ - ::SetLastError(lastError); -} - -static_assert(ERROR_INVALID_ORDINAL == 182, "dang!");
\ No newline at end of file diff --git a/shared/FindFilePlus/load_dll.h b/shared/FindFilePlus/load_dll.h deleted file mode 100644 index f152dd74..00000000 --- a/shared/FindFilePlus/load_dll.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************** -// * 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 LOAD_DLL_HEADER_0312463214872163832174 -#define LOAD_DLL_HEADER_0312463214872163832174 - -namespace dll -{ -template <typename FunctionType> -FunctionType getSystemDllFun(const wchar_t* libraryName, const char* functionName); //NOTE: uses ::GetModuleHandle => call for system DLLs only! - -void setWin32Error(unsigned long lastError); - - - - - - - - - - - - - -void* /*FARPROC*/ loadSymbol(const wchar_t* libraryName, const char* functionName); - -template <typename FunctionType> inline -FunctionType getSystemDllFun(const wchar_t* libraryName, const char* functionName) -{ - return reinterpret_cast<FunctionType>(loadSymbol(libraryName, functionName)); -} -} - -#endif //LOAD_DLL_HEADER_0312463214872163832174 - diff --git a/shared/IFileOperation/FileOperation_Vista.vcxproj b/shared/IFileOperation/FileOperation_Vista.vcxproj deleted file mode 100644 index 5de402f4..00000000 --- a/shared/IFileOperation/FileOperation_Vista.vcxproj +++ /dev/null @@ -1,236 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>Vista IFileOperation</ProjectName> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">FileOperation_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">FileOperation_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">FileOperation_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">FileOperation_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="file_op.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="file_op.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/IFileOperation/dll_main.cpp b/shared/IFileOperation/dll_main.cpp deleted file mode 100644 index 3805c99d..00000000 --- a/shared/IFileOperation/dll_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -//optional: add init/teardown logic here -BOOL APIENTRY DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - 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 deleted file mode 100644 index 8b632972..00000000 --- a/shared/IFileOperation/file_op.cpp +++ /dev/null @@ -1,235 +0,0 @@ -// ************************************************************************** -// * 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 "file_op.h" -#include "../com_ptr.h" -#include "../com_error.h" -#include "../c_dll.h" - -#include <Shellapi.h> // Included for shell constants such as FO_* values -#include <shobjidl.h> // Required for necessary shell dependencies -#include <comdef.h> -#include <algorithm> -#include <string> -#include <cstdio> -#define WIN32_LEAN_AND_MEAN -#include "windows.h" - -using namespace c_dll; - - -namespace fileop -{ -std::wstring lastErrorMessage; -} - - -bool fileop::moveToRecycleBin(const wchar_t* fileNames[], - size_t fileNo) //size of fileNames array -{ - using util::ComPtr; - using util::generateErrorMsg; - HRESULT hr; - - // Create the IFileOperation interface - ComPtr<IFileOperation> fileOp; - hr = ::CoCreateInstance(CLSID_FileOperation, - NULL, - CLSCTX_ALL, - IID_PPV_ARGS(fileOp.init())); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr); - return false; - } - - // Set the operation flags. Turn off all UI - // from being shown to the user during the - // operation. This includes error, confirmation - // and progress dialogs. - hr = fileOp->SetOperationFlags(FOF_ALLOWUNDO | - FOF_NOCONFIRMATION | - FOF_SILENT | - FOFX_EARLYFAILURE | - FOF_NOERRORUI); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr); - return false; - } - - int operationCount = 0; - - for (size_t i = 0; i < fileNo; ++i) - { - //create file/folder item object - ComPtr<IShellItem> psiFile; - hr = ::SHCreateItemFromParsingName(fileNames[i], - NULL, - 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"\"."; - - lastErrorMessage = generateErrorMsg(message, hr); - return false; - } - - hr = fileOp->DeleteItem(psiFile.get(), NULL); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"DeleteItem\".", hr); - return false; - } - - ++operationCount; - } - - if (operationCount == 0) //calling PerformOperations() without anything to do results in E_UNEXPECTED - return true; - - //perform actual operations - hr = fileOp->PerformOperations(); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr); - return false; - } - - //check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors! - BOOL pfAnyOperationsAborted = FALSE; - hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr); - return false; - } - - if (pfAnyOperationsAborted == TRUE) - { - lastErrorMessage = L"Operation did not complete successfully."; - return false; - } - - return true; -} - - -bool fileop::copyFile(const wchar_t* sourceFile, - const wchar_t* targetFile) -{ - using util::ComPtr; - using util::generateErrorMsg; - - HRESULT hr; - - // Create the IFileOperation interface - ComPtr<IFileOperation> fileOp; - hr = ::CoCreateInstance(CLSID_FileOperation, - NULL, - CLSCTX_ALL, - IID_PPV_ARGS(fileOp.init())); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr); - return false; - } - - // Set the operation flags. Turn off all UI - // from being shown to the user during the - // operation. This includes error, confirmation - // and progress dialogs. - hr = fileOp->SetOperationFlags(FOF_NOCONFIRMATION | - FOF_SILENT | - FOFX_EARLYFAILURE | - FOF_NOERRORUI); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr); - return false; - } - - //create source object - ComPtr<IShellItem> psiSourceFile; - hr = ::SHCreateItemFromParsingName(sourceFile, - NULL, - IID_PPV_ARGS(psiSourceFile.init())); - if (FAILED(hr)) - { - std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n"); - message += std::wstring(L"\"") + sourceFile + L"\"."; - lastErrorMessage = generateErrorMsg(message, hr); - return false; - } - - const size_t pos = std::wstring(targetFile).find_last_of(L'\\'); - if (pos == std::wstring::npos) - { - lastErrorMessage = L"Target filename does not contain a path separator."; - return false; - } - - const std::wstring targetFolder(targetFile, pos); - const std::wstring targetFileNameShort = targetFile + pos + 1; - - //create target folder object - ComPtr<IShellItem> psiTargetFolder; - hr = ::SHCreateItemFromParsingName(targetFolder.c_str(), - NULL, - IID_PPV_ARGS(psiTargetFolder.init())); - if (FAILED(hr)) - { - std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n"); - message += std::wstring(L"\"") + targetFolder + L"\"."; - lastErrorMessage = generateErrorMsg(message, hr); - return false; - } - - //schedule file copy operation - hr = fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), NULL); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"CopyItem\".", hr); - return false; - } - - //perform actual operations - hr = fileOp->PerformOperations(); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr); - return false; - } - - //check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors! - BOOL pfAnyOperationsAborted = FALSE; - hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted); - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr); - return false; - } - - if (pfAnyOperationsAborted == TRUE) - { - lastErrorMessage = L"Operation did not complete successfully."; - return false; - } - - return true; -} - - -//if any of the functions above returns 'false', this message returns last error -void fileop::getLastError(wchar_t* errorMessage, size_t errorBufferLen) -{ - writeString(lastErrorMessage, errorMessage, errorBufferLen); -} diff --git a/shared/IFileOperation/file_op.h b/shared/IFileOperation/file_op.h deleted file mode 100644 index dbe00196..00000000 --- a/shared/IFileOperation/file_op.h +++ /dev/null @@ -1,62 +0,0 @@ -// ************************************************************************** -// * 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 RECYCLER_DLL_H -#define RECYCLER_DLL_H - -#ifdef FILE_OP_DLL_EXPORTS -#define FILE_OP_DLL_API extern "C" __declspec(dllexport) -#else -#define FILE_OP_DLL_API extern "C" __declspec(dllimport) -#endif - -#include "../build_info.h" - - -namespace fileop -{ -/*-------------- - |declarations| - --------------*/ - -//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize - -FILE_OP_DLL_API -bool moveToRecycleBin(const wchar_t* fileNames[], - size_t fileNo); //size of fileNames array - -FILE_OP_DLL_API -bool copyFile(const wchar_t* sourceFile, - const wchar_t* targetFile); - -//if any of the functions above returns 'false', this message returns last error -FILE_OP_DLL_API -void getLastError(wchar_t* errorMessage, size_t errorBufferLen); - -/*---------- - |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); - -/*-------------- - |symbol names| - --------------*/ -//(use const pointers to ensure internal linkage) -const char moveToRecycleBinFctName[] = "moveToRecycleBin"; -const char copyFileFctName[] = "copyFile"; -const char getLastErrorFctName[] = "getLastError"; - -/*--------------- - |library names| - ---------------*/ -inline const wchar_t* getDllName() { return util::is64BitBuild ? L"FileOperation_x64.dll" : L"FileOperation_Win32.dll"; } -} - - - -#endif //RECYCLER_DLL_H diff --git a/shared/ShadowCopy/LockFile.cpp b/shared/ShadowCopy/LockFile.cpp deleted file mode 100644 index 7df3ec66..00000000 --- a/shared/ShadowCopy/LockFile.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************** -// * 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 <string> -#include <iostream> -#define WIN32_LEAN_AND_MEAN -#include "windows.h" - -int wmain(int argc, wchar_t* argv[]) -{ - if (argc <= 1) - { - std::wcout << "Please enter the filename to be locked as %1 parameter!" << "\n\n"; - system("pause"); - return -1; - } - std::wstring filename = argv[1]; - - //obtain exclusive lock on test file - HANDLE hFile = ::CreateFile(filename.c_str(), - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - std::wcout << "Error obtaining exclusive lock on test file: " << filename << "\n\n"; - system("pause"); - return -1; - } - - std::wcout << "File " << filename << " is locked! Press a key to unlock." << "\n\n"; - system("pause"); - - ::CloseHandle(hFile); - return 0; -} - diff --git a/shared/ShadowCopy/Shadow_2003.vcxproj b/shared/ShadowCopy/Shadow_2003.vcxproj deleted file mode 100644 index 710b65bf..00000000 --- a/shared/ShadowCopy/Shadow_2003.vcxproj +++ /dev/null @@ -1,240 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>Server2003</ProjectName> - <ProjectGuid>{2F2994D6-FB89-4BAA-A5DF-03BAF7337FF2}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <UseOfAtl>false</UseOfAtl> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="shadow.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="shadow.h" /> - </ItemGroup> - <ItemGroup> - <Library Include="Server 2003\lib\$(Platform)\vssapi.lib" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/ShadowCopy/Shadow_XP.vcxproj b/shared/ShadowCopy/Shadow_XP.vcxproj deleted file mode 100644 index 6211afd5..00000000 --- a/shared/ShadowCopy/Shadow_XP.vcxproj +++ /dev/null @@ -1,241 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>XP</ProjectName> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="shadow.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="shadow.h" /> - </ItemGroup> - <ItemGroup> - <Library Include="XP\lib\$(Platform)\vssapi.lib" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/ShadowCopy/dll_main.cpp b/shared/ShadowCopy/dll_main.cpp deleted file mode 100644 index 3805c99d..00000000 --- a/shared/ShadowCopy/dll_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -//optional: add init/teardown logic here -BOOL APIENTRY DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - 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.cpp b/shared/ShadowCopy/shadow.cpp deleted file mode 100644 index 8b7b9971..00000000 --- a/shared/ShadowCopy/shadow.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// ************************************************************************** -// * 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 "shadow.h" -#include <algorithm> -#include <string> -#include <comdef.h> -#include "../com_ptr.h" -#include "../com_error.h" -#include "../c_dll.h" - -#define WIN32_LEAN_AND_MEAN -#include "windows.h" - -#ifdef USE_SHADOW_XP -#include "xp/inc/vss.h" -#include "xp/inc/vswriter.h" -#include "xp/inc/vsbackup.h" - -#elif defined USE_SHADOW_2003 -#include "Server 2003/inc/vss.h" -#include "Server 2003/inc/vswriter.h" -#include "Server 2003/inc/vsbackup.h" -#else -adapt! -#endif - -using namespace c_dll; - - -namespace -{ -typedef HandleProvider<shadow::ShadowHandle, util::ComPtr<IVssBackupComponents> > HandleShadowMap; - -void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned int outputBufferLen) -{ - writeString(util::generateErrorMsg(input, hr).c_str(), output, outputBufferLen); -} -} - - -bool shadow::createShadowCopy(const wchar_t* volumeName, - wchar_t* shadowVolName, - unsigned int shadowBufferLen, - ShadowHandle* handle, - wchar_t* errorMessage, - unsigned int errorBufferLen) -{ - using util::ComPtr; - using util::generateErrorMsg; - - //MessageBox(0, L"backup err", L"", 0); */ - *handle = 0; - HRESULT hr = NULL; - - ComPtr<IVssBackupComponents> backupComp; - if (FAILED(hr = CreateVssBackupComponents(backupComp.init()))) - { - if (hr == E_ACCESSDENIED) - writeErrorMsg(L"The caller does not have sufficient backup privileges or is not an administrator.", hr, errorMessage, errorBufferLen); - else - writeErrorMsg(L"Error calling \"CreateVssBackupComponents\".", hr, errorMessage, errorBufferLen); - return false; - } - - if (FAILED(hr = backupComp->InitializeForBackup())) - { - writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen); - return false; - } - - if (FAILED(hr = backupComp->SetBackupState(false, false, VSS_BT_FULL))) - { - writeErrorMsg(L"Error calling \"SetBackupState\".", hr, errorMessage, errorBufferLen); - return false; - } - - ComPtr<IVssAsync> vssWriters; - if (FAILED(hr = backupComp->GatherWriterMetadata(vssWriters.init()))) - { - //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build) - writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen); - return false; - } - - //wait for shadow copy writers to complete - if (FAILED(hr = vssWriters->Wait())) - { - writeErrorMsg(L"Error calling \"vssWriters->Wait\".", hr, errorMessage, errorBufferLen); - return false; - } - - vssWriters->QueryStatus(&hr, NULL); //check if the async operation succeeded... - if (FAILED(hr)) - { - writeErrorMsg(L"Error calling \"vssWriters->QueryStatus\".", hr, errorMessage, errorBufferLen); - return false; - } - - VSS_ID snapshotSetId = {0}; - if (FAILED(hr = backupComp->StartSnapshotSet(&snapshotSetId))) - { - writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen); - return false; - } - - VSS_ID SnapShotId = {0}; - if (FAILED(hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId))) - { - writeErrorMsg(L"Error calling \"AddToSnapshotSet\".", hr, errorMessage, errorBufferLen); - return false; - } - - ComPtr<IVssAsync> vssPrepare; - if (FAILED(hr = backupComp->PrepareForBackup(vssPrepare.init()))) - { - writeErrorMsg(L"Error calling \"PrepareForBackup\".", hr, errorMessage, errorBufferLen); - return false; - } - - if (FAILED(hr = vssPrepare->Wait())) - { - writeErrorMsg(L"Error calling \"vssPrepare->Wait\".", hr, errorMessage, errorBufferLen); - return false; - } - - vssPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded... - if (FAILED(hr)) - { - writeErrorMsg(L"Error calling \"vssPrepare->QueryStatus\".", hr, errorMessage, errorBufferLen); - return false; - } - - ComPtr<IVssAsync> vssDoShadowCopy; - if (FAILED(hr = backupComp->DoSnapshotSet(vssDoShadowCopy.init()))) - { - writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen); - return false; - } - - if (FAILED(hr = vssDoShadowCopy->Wait())) - { - writeErrorMsg(L"Error calling \"vssDoShadowCopy->Wait\".", hr, errorMessage, errorBufferLen); - return false; - } - - vssDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded... - if (FAILED(hr)) - { - writeErrorMsg(L"Error calling \"vssDoShadowCopy->QueryStatus\".", hr, errorMessage, errorBufferLen); - return false; - } - - VSS_SNAPSHOT_PROP props; - if (FAILED(hr = backupComp->GetSnapshotProperties(SnapShotId, &props))) - { - writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen); - return false; - } - - //finally: write volume name of newly created shadow copy - writeString(props.m_pwszSnapshotDeviceObject, shadowVolName, shadowBufferLen); - - VssFreeSnapshotProperties(&props); - - *handle = HandleShadowMap::instance().insert(backupComp); - - return true; -} - - -void shadow::releaseShadowCopy(ShadowHandle handle) -{ - HandleShadowMap::instance().remove(handle); -} diff --git a/shared/ShadowCopy/shadow.h b/shared/ShadowCopy/shadow.h deleted file mode 100644 index 8721b906..00000000 --- a/shared/ShadowCopy/shadow.h +++ /dev/null @@ -1,106 +0,0 @@ -// ************************************************************************** -// * 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 SHADOWCOPY_H -#define SHADOWCOPY_H - -#ifdef SHADOWDLL_EXPORTS -#define SHADOWDLL_API extern "C" __declspec(dllexport) -#else -#define SHADOWDLL_API extern "C" __declspec(dllimport) -#endif - -#include "../build_info.h" - - -namespace shadow -{ -/*-------------- - |declarations| - --------------*/ - -//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize - -typedef size_t ShadowHandle; - -//volumeName must end with "\", while shadowVolName does not end with "\" -SHADOWDLL_API -bool createShadowCopy(const wchar_t* volumeName, //[in] - wchar_t* shadowVolName, //[out] - unsigned int shadowBufferLen, //[in] - ShadowHandle* handle, //[out] - wchar_t* errorMessage, //[out] - unsigned int errorBufferLen); //[in] - - -//don't forget to release the backupHandle after shadow copy is not needed anymore! -SHADOWDLL_API -void releaseShadowCopy(ShadowHandle handle); - - -//########################################################################################## - - -/*---------- - |typedefs| - ----------*/ -typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName, - wchar_t* shadowVolName, - unsigned int shadowBufferLen, - ShadowHandle* handle, - wchar_t* errorMessage, - unsigned int errorBufferLen); - -typedef void (*ReleaseShadowCopyFct)(ShadowHandle handle); - -/*-------------- - |symbol names| - --------------*/ -//(use const pointers to ensure internal linkage) -const char createShadowCopyFctName[] = "createShadowCopy"; -const char releaseShadowCopyFctName[] = "releaseShadowCopy"; - -/*--------------- - |library names| - ---------------*/ -namespace impl -{ -bool newerThanXP() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if (::GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5 || - (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 1) ; - //XP has majorVersion == 5, minorVersion == 1 - //Server 2003 has majorVersion == 5, minorVersion == 2 - //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} -} - -inline -const wchar_t* getDllName() -{ - /* - distinguish a bunch of VSS builds: we use XP and Server 2003 implementations... - VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx - */ - return impl::newerThanXP() ? - (util::is64BitBuild ? - L"Shadow_Server2003_x64.dll" : - L"Shadow_Server2003_Win32.dll") : - - (util::is64BitBuild ? - L"Shadow_XP_x64.dll" : - L"Shadow_XP_Win32.dll"); -} -} - - - -#endif //SHADOWCOPY_H diff --git a/shared/Taskbar_Seven/Taskbar_Seven.vcxproj b/shared/Taskbar_Seven/Taskbar_Seven.vcxproj deleted file mode 100644 index 8437bc09..00000000 --- a/shared/Taskbar_Seven/Taskbar_Seven.vcxproj +++ /dev/null @@ -1,234 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Taskbar7_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Taskbar7_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Taskbar7_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Taskbar7_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="taskbar.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="taskbar.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/Taskbar_Seven/dll_main.cpp b/shared/Taskbar_Seven/dll_main.cpp deleted file mode 100644 index 3805c99d..00000000 --- a/shared/Taskbar_Seven/dll_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -//optional: add init/teardown logic here -BOOL APIENTRY DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - 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 deleted file mode 100644 index 2a739e6c..00000000 --- a/shared/Taskbar_Seven/taskbar.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// ************************************************************************** -// * 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 "taskbar.h" - -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#include <ShObjIdl.h> - -#include <map> -#include <string> -#include <comdef.h> -#include "../com_error.h" -#include "../com_ptr.h" -#include "../c_dll.h" - -using namespace util; -using namespace c_dll; - -namespace -{ -std::wstring lastErrorMessage; - - -ComPtr<ITaskbarList3> getInstance() -{ - static ComPtr<ITaskbarList3> taskbarlist; - if (!taskbarlist) - { - HRESULT hr = ::CoCreateInstance(CLSID_TaskbarList, - NULL, - CLSCTX_ALL, - IID_PPV_ARGS(taskbarlist.init())); - if (FAILED(hr)) - lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr); - } - - return taskbarlist; -} - -} -//################################################################################################## - - -bool tbseven::setStatus(void* hwnd, //HWND: window assciated to the taskbar icon - 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; - } - - ComPtr<ITaskbarList3> taskbarlist = getInstance(); - if (!taskbarlist) //error msg already set - return false; - - HRESULT hr = taskbarlist->SetProgressState(static_cast<HWND>(hwnd), //[in] HWND hwnd, - flag); //[in] TBPFLAG tbpFlags - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"SetProgressState\".", hr); - return false; - } - - return true; -} - - -bool tbseven::setProgress(void* hwnd, //HWND: window assciated to the taskbar icon - size_t current, - size_t total) -{ - ComPtr<ITaskbarList3> taskbarlist = getInstance(); - if (!taskbarlist) //error msg already set - return false; - - HRESULT hr = taskbarlist->SetProgressValue( - static_cast<HWND>(hwnd), //[in] HWND hwnd, - current, //[in] ULONGLONG ullCompleted, - total); //[in] ULONGLONG ullTotal - if (FAILED(hr)) - { - lastErrorMessage = generateErrorMsg(L"Error calling \"SetProgressValue\".", hr); - return false; - } - - return true; -} - - -void tbseven::getLastError(wchar_t* errorMessage, size_t errorBufferLen) -{ - writeString(lastErrorMessage, errorMessage, errorBufferLen); -} diff --git a/shared/Taskbar_Seven/taskbar.h b/shared/Taskbar_Seven/taskbar.h deleted file mode 100644 index 507920c7..00000000 --- a/shared/Taskbar_Seven/taskbar.h +++ /dev/null @@ -1,72 +0,0 @@ -// ************************************************************************** -// * 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 TASKBAR_SEVEN_DLL_H -#define TASKBAR_SEVEN_DLL_H - -#ifdef TASKBAR_SEVEN_DLL_EXPORTS -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport) -#else -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport) -#endif - -#include "../build_info.h" - - -namespace tbseven -{ -/*-------------- - |declarations| - --------------*/ - -enum TaskBarStatus -{ - STATUS_NOPROGRESS, - STATUS_INDETERMINATE, - STATUS_NORMAL, - STATUS_ERROR, - STATUS_PAUSED -}; - - -//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize - -DLL_FUNCTION_DECLARATION -bool setStatus(void* hwnd, //HWND: window assciated to the taskbar icon - TaskBarStatus status); - - -DLL_FUNCTION_DECLARATION -bool setProgress(void* hwnd, //HWND: window assciated to the taskbar icon - size_t current, - size_t total); - -//if any of the functions above returns 'false', this message returns last error -DLL_FUNCTION_DECLARATION -void getLastError(wchar_t* errorMessage, size_t errorBufferLen); - -/*---------- - |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); - -/*-------------- - |symbol names| - --------------*/ -//(use const pointers to ensure internal linkage) -const char setStatusFctName[] = "setStatus"; -const char setProgressFctName[] = "setProgress"; -const char getLastErrorFctName[] = "getLastError"; - -/*--------------- - |library names| - ---------------*/ -inline const wchar_t* getDllName() { return util::is64BitBuild ? L"Taskbar7_x64.dll" : L"Taskbar7_Win32.dll"; } -} - -#endif //TASKBAR_SEVEN_DLL_H diff --git a/shared/Thumbnail/Thumbnail.vcxproj b/shared/Thumbnail/Thumbnail.vcxproj deleted file mode 100644 index 05196e0a..00000000 --- a/shared/Thumbnail/Thumbnail.vcxproj +++ /dev/null @@ -1,235 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Thumbnail_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Thumbnail_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Thumbnail_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Thumbnail_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="dll_main.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </PrecompiledHeader> - <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> - </ClCompile> - <ClCompile Include="thumbnail.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="thumbnail.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/shared/Thumbnail/dll_main.cpp b/shared/Thumbnail/dll_main.cpp deleted file mode 100644 index 3805c99d..00000000 --- a/shared/Thumbnail/dll_main.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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) * -// ************************************************************************** - - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -//optional: add init/teardown logic here -BOOL APIENTRY DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - case DLL_PROCESS_DETACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - } - return TRUE; -} diff --git a/shared/Thumbnail/thumbnail.cpp b/shared/Thumbnail/thumbnail.cpp deleted file mode 100644 index 51635ff9..00000000 --- a/shared/Thumbnail/thumbnail.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// ************************************************************************** -// * 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 "thumbnail.h" - -#define WIN32_LEAN_AND_MEAN -#include "windows.h" - -#define STRICT_TYPED_ITEMIDS //better type safety for IDLists -#include <Shlobj.h> - -#include <Shellapi.h> -#include <CommonControls.h> -#include "../com_ptr.h" -#include "../string_tools.h" -#include "../loki/ScopeGuard.h" -//#include "../perf.h" - -using namespace zen; - - -thumb::HICON thumb::getThumbnail(const wchar_t* filename, int requestedSize) //return 0 on failure, caller takes ownership! -{ - const std::wstring filenameStr(filename); - - util::ComPtr<IShellFolder> shellFolder; - { - HRESULT hr = ::SHGetDesktopFolder(shellFolder.init()); - if (FAILED(hr) || !shellFolder) - return NULL; - } - - PIDLIST_RELATIVE pidlFolder = NULL; - { - const std::wstring pathName = beforeLast(filenameStr, '\\'); - HRESULT hr = shellFolder->ParseDisplayName(NULL, // [in] HWND hwnd, - NULL, // [in] IBindCtx *pbc, - const_cast<LPWSTR>(pathName.c_str()), // [in] LPWSTR pszDisplayName, - NULL, // [out] ULONG *pchEaten, - &pidlFolder, // [out] PIDLIST_RELATIVE* ppidl, - NULL); // [in, out] ULONG *pdwAttributes - if (FAILED(hr) || !pidlFolder) - return NULL; - } - LOKI_ON_BLOCK_EXIT2(::ILFree(pidlFolder)); //older version: ::CoTaskMemFree - - util::ComPtr<IShellFolder> imageFolder; - { - HRESULT hr = shellFolder->BindToObject(pidlFolder, // [in] PCUIDLIST_RELATIVE pidl, - NULL, - IID_PPV_ARGS(imageFolder.init())); - if (FAILED(hr) || !imageFolder) - return NULL; - } - - PIDLIST_RELATIVE pidImage = NULL; - { - const std::wstring shortName = afterLast(filenameStr, '\\'); - HRESULT hr = imageFolder->ParseDisplayName(NULL, // [in] HWND hwnd, - NULL, // [in] IBindCtx *pbc, - const_cast<LPWSTR>(shortName.c_str()), // [in] LPWSTR pszDisplayName, - NULL, // [out] ULONG *pchEaten, - &pidImage, // [out] PIDLIST_RELATIVE *ppidl, - NULL); // [in, out] ULONG *pdwAttributes - if (FAILED(hr) || !pidImage) - return NULL; - } - LOKI_ON_BLOCK_EXIT2(::ILFree(pidImage)); //older version: ::CoTaskMemFree - - util::ComPtr<IExtractImage> extractImage; - { - PCUITEMID_CHILD_ARRAY pidlIn = reinterpret_cast<PCUITEMID_CHILD_ARRAY>(&pidImage); - //this is where STRICT_TYPED_ITEMIDS gets us ;) - - HRESULT hr = imageFolder->GetUIObjectOf(NULL, // [in] HWND hwndOwner, - 1, // [in] UINT cidl, - pidlIn, // [in] PCUITEMID_CHILD_ARRAY apidl, - IID_IExtractImage, // [in] REFIID riid, - NULL, // [in, out] UINT *rgfReserved, - reinterpret_cast<void**>(extractImage.init())); // [out] void **ppv - if (FAILED(hr) || !extractImage) - return NULL; - } - - { - wchar_t pathBuffer[MAX_PATH]; - DWORD priority = 0; - const SIZE prgSize = { requestedSize, requestedSize }; //preferred size only! - DWORD clrDepth = 32; - DWORD flags = IEIFLAG_SCREEN | IEIFLAG_OFFLINE; - - HRESULT hr = extractImage->GetLocation(pathBuffer, // [out] LPWSTR pszPathBuffer, - MAX_PATH, // [in] DWORD cchMax, - &priority, // [out] DWORD *pdwPriority, - &prgSize, // [in] const SIZE *prgSize, - clrDepth, // [in] DWORD dwRecClrDepth, - &flags); // [in, out] DWORD *pdwFlags - if (FAILED(hr)) - return NULL; - } - - HBITMAP bitmap = NULL; - { - HRESULT hr = extractImage->Extract(&bitmap); - if (FAILED(hr) || !bitmap) - return NULL; - } - LOKI_ON_BLOCK_EXIT2(::DeleteObject(bitmap)); - - - BITMAP bmpInfo = {}; - if (::GetObject(bitmap, //__in HGDIOBJ hgdiobj, - sizeof(bmpInfo), //__in int cbBuffer, - &bmpInfo) == 0) //__out LPVOID lpvObject - return NULL; - - HBITMAP bitmapMask = ::CreateCompatibleBitmap(::GetDC(NULL), bmpInfo.bmWidth, bmpInfo.bmHeight); - if (bitmapMask == 0) - return NULL; - LOKI_ON_BLOCK_EXIT2(::DeleteObject(bitmapMask)); - - ICONINFO iconInfo = {}; - iconInfo.fIcon = true; - iconInfo.hbmColor = bitmap; - iconInfo.hbmMask = bitmapMask; - - return ::CreateIconIndirect(&iconInfo); -} - - -thumb::HICON thumb::getIconByIndex(int iconIndex, int shilIconType) //return 0 on failure, caller takes ownership! -{ - //Note: using IExtractIcon::Extract is *no* alternative, just as ::SHGetFileInfo(), it only supports small (16x16) and large (32x32) icons - - util::ComPtr<IImageList> imageList; //perf: 0,12 µs only to get the image list - { - HRESULT hr = ::SHGetImageList(shilIconType, //__in int iImageList, - IID_PPV_ARGS(imageList.init())); - if (FAILED(hr) || !imageList) - return NULL; - } - - bool hasAlpha = false; //perf: 0,14 µs - { - DWORD flags = 0; - HRESULT hr = imageList->GetItemFlags(iconIndex, //[in] int i, - &flags); //[out] DWORD *dwFlags - if (SUCCEEDED(hr)) - hasAlpha = flags & ILIF_ALPHA; - } - - ::HICON hIcon = NULL; //perf: 1,5 ms - the dominant block - { - HRESULT hr = imageList->GetIcon(iconIndex, // [in] int i, - hasAlpha ? ILD_IMAGE : ILD_NORMAL, // [in] UINT flags, - //ILD_IMAGE -> do not draw mask - fixes glitch with ILD_NORMAL where both mask *and* alpha channel are applied, e.g. for ffs_batch and folder icon - //other flags: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775230(v=vs.85).aspx - &hIcon); // [out] HICON *picon - if (FAILED(hr) || !hIcon) - return NULL; - } - - return hIcon; -}
\ No newline at end of file diff --git a/shared/Thumbnail/thumbnail.h b/shared/Thumbnail/thumbnail.h deleted file mode 100644 index ae62cf5d..00000000 --- a/shared/Thumbnail/thumbnail.h +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************** -// * 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 TASKBAR_SEVEN_DLL_H -#define TASKBAR_SEVEN_DLL_H - -#ifdef THUMBNAIL_DLL_EXPORTS -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport) -#else -#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport) -#endif - -#include "../build_info.h" -//#include <WinDef.h> - -namespace thumb -{ -/* -PREREQUISITES: - -1. COM must be initialized for the current thread via ::CoInitialize(NULL) or ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), - but NOT ::CoInitializeEx(NULL, COINIT_MULTITHREADED) -> internal access violation crash! -2. call ::FileIconInit() on app start to remedy obscure errors like SHELL_E_WRONG_BITDEPTH (0x80270102) - for certain file types, e.g. lnk, mpg - required on Windows 7 see http://msdn.microsoft.com/en-us/library/ms683212(v=VS.85).aspx -*/ - -/*-------------- - |declarations| - --------------*/ -typedef void* HICON; - -DLL_FUNCTION_DECLARATION -HICON getThumbnail(const wchar_t* filename, int requestedSize); //return 0 on failure, caller takes ownership! -//Note: not all file types support thumbnails! make sure to implement fallback to file icon! - -DLL_FUNCTION_DECLARATION -HICON getIconByIndex(int iconIndex, int shilIconType); //return 0 on failure, caller takes ownership! -/* -"iconType" refers to parameter "iImageList" of ::SHGetImageList(); sample values: - SHIL_SMALL - 16x16, but the size can be customized by the user. - SHIL_EXTRALARGE - 48x48, but the size can be customized by the user. - SHIL_JUMBO - Vista and later; normally 256x256 pixels -"iconIndex" as returned by ::SHGetFileInfo() -*/ - -/*---------- - |typedefs| - ----------*/ -typedef HICON (*GetThumbnailFct )(const wchar_t* filename, int requestedSize); -typedef HICON (*GetIconByIndexFct)(int iconIndex, int shilIconType); - -/*-------------- - |symbol names| - --------------*/ -//(use const pointers to ensure internal linkage) -const char getThumbnailFctName [] = "getThumbnail"; -const char getIconByIndexFctName [] = "getIconByIndex"; - -/*--------------- - |library names| - ---------------*/ -inline const wchar_t* getDllName() { return util::is64BitBuild ? L"Thumbnail_x64.dll" : L"Thumbnail_Win32.dll"; } -} - -#endif //TASKBAR_SEVEN_DLL_H diff --git a/shared/app_main.cpp b/shared/app_main.cpp deleted file mode 100644 index 28ce1e09..00000000 --- a/shared/app_main.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// ************************************************************************** -// * 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 "app_main.h" -#include <wx/window.h> -#include <wx/app.h> - -using namespace zen; - - -bool AppMainWindow::mainWndActive = false; - - -void zen::AppMainWindow::setMainWindow(wxWindow* window) -{ - wxTheApp->SetTopWindow(window); - wxTheApp->SetExitOnFrameDelete(true); - - mainWndActive = true; -} - - -bool AppMainWindow::mainWindowWasSet() -{ - return mainWndActive; -} diff --git a/shared/app_main.h b/shared/app_main.h deleted file mode 100644 index fa538771..00000000 --- a/shared/app_main.h +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************** -// * 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 APPMAIN_H_INCLUDED -#define APPMAIN_H_INCLUDED - -class wxWindow; - -namespace zen -{ -//just some wrapper around a global variable representing the (logical) main application window -class AppMainWindow -{ -public: - static void setMainWindow(wxWindow* window); //set main window and enable "exit on frame delete" - static bool mainWindowWasSet(); - -private: - static bool mainWndActive; -}; -} - - -#endif // APPMAIN_H_INCLUDED diff --git a/shared/assert_static.h b/shared/assert_static.h deleted file mode 100644 index 9b1a189e..00000000 --- a/shared/assert_static.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************** -// * This file is part of the zenXML project. It is distributed under the * -// * Boost Software License, Version 1.0. See accompanying file * -// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * -// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * -// ************************************************************************** - -#ifndef ASSERTSTATIC_H_INCLUDED -#define ASSERTSTATIC_H_INCLUDED - -//compile time assert based on Loki (http://loki-lib.sourceforge.net) - -#ifdef NDEBUG - -#define assert_static(x) //((void)0) -> leads to error when seen in namespace scope! - -#else /* debugging enabled */ -namespace StaticCheckImpl -{ -template<int> -struct CompileTimeError; - -template<> -struct CompileTimeError<true> {}; -} - -#define LOKI_CONCAT( X, Y ) LOKI_CONCAT_SUB( X, Y ) -#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) >) } - -/*#define assert_static(expr) \ -{ Loki::CompileTimeError<((expr) != 0)> Static_Assert_Has_Failed; (void)Static_Assert_Has_Failed; } */ - -#endif - -#endif //ASSERTSTATIC_H_INCLUDED diff --git a/shared/base64.h b/shared/base64.h deleted file mode 100644 index 4a81787c..00000000 --- a/shared/base64.h +++ /dev/null @@ -1,159 +0,0 @@ -// ************************************************************************** -// * This file is part of the zenXML project. It is distributed under the * -// * Boost Software License, Version 1.0. See accompanying file * -// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * -// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * -// ************************************************************************** -#ifndef BASE64_HEADER_08473021856321840873021487213453214 -#define BASE64_HEADER_08473021856321840873021487213453214 - -#include <iterator> -#include <cassert> -#include "assert_static.h" - -namespace zen -{ -//http://en.wikipedia.org/wiki/Base64 -/* -Usage: - const std::string input = "Sample text"; - std::string output; - zen::encodeBase64(input.begin(), input.end(), std::back_inserter(output)); - //output contains "U2FtcGxlIHRleHQ=" -*/ -template <class InputIterator, class OutputIterator> -OutputIterator encodeBase64(InputIterator first, InputIterator last, OutputIterator result); //throw () - -template <class InputIterator, class OutputIterator> -OutputIterator decodeBase64(InputIterator first, InputIterator last, OutputIterator result); //throw () - - - - - - - - - - - - - - - - -//---------------------------------------- implementation ---------------------------------------- -namespace implementation -{ -const char ENCODING_MIME[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; //64 chars for base64 encoding + padding char -const signed char DECODING_MIME[] = -{ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 -}; -const size_t INDEX_PAD = 64; -} - - -//http://en.wikipedia.org/wiki/Base64 -template <class InputIterator, class OutputIterator> inline -OutputIterator encodeBase64(InputIterator first, InputIterator last, OutputIterator result) -{ - using namespace implementation; - assert_static(sizeof(std::iterator_traits<InputIterator>::value_type) == 1); - assert_static(sizeof(ENCODING_MIME) == 65 + 1); - - while (first != last) - { - const unsigned char a = *first++; - *result++ = ENCODING_MIME[a >> 2]; - - if (first == last) - { - *result++ = ENCODING_MIME[((a & 0x3) << 4)]; - *result++ = ENCODING_MIME[INDEX_PAD]; - *result++ = ENCODING_MIME[INDEX_PAD]; - break; - } - const unsigned char b = *first++; - *result++ = ENCODING_MIME[((a & 0x3) << 4) | (b >> 4)]; - - if (first == last) - { - *result++ = ENCODING_MIME[((b & 0xf) << 2)]; - *result++ = ENCODING_MIME[INDEX_PAD]; - break; - } - const unsigned char c = *first++; - *result++ = ENCODING_MIME[((b & 0xf) << 2) | (c >> 6)]; - *result++ = ENCODING_MIME[c & 0x3f]; - } - - return result; -} - - -template <class InputIterator, class OutputIterator> inline -OutputIterator decodeBase64(InputIterator first, InputIterator last, OutputIterator result) -{ - using namespace implementation; - assert_static(sizeof(std::iterator_traits<InputIterator>::value_type) == 1); - assert_static(sizeof(DECODING_MIME) == 128); - - const int INDEX_END = INDEX_PAD + 1; - - auto readIndex = [&]() -> unsigned char //return index within [0, 64] or INDEX_END if end of input - { - while (true) - { - if (first == last) - return INDEX_END; - - unsigned char ch = *first++; - if (ch < 128) //skip all unknown characters (including carriage return, line-break, tab) - { - const int index = implementation::DECODING_MIME[ch]; - if (0 <= index && index <= INDEX_PAD) //respect padding - return index; - } - } - }; - - while (true) - { - const unsigned char index1 = readIndex(); - const unsigned char index2 = readIndex(); - if (index1 >= INDEX_PAD || index2 >= INDEX_PAD) - { - assert(index1 == INDEX_END && index2 == INDEX_END); - break; - } - *result++ = (index1 << 2) | (index2 >> 4); - - const unsigned char index3 = readIndex(); - if (index3 >= INDEX_PAD) //padding - { - assert(index3 == INDEX_PAD); - break; - } - *result++ = ((index2 & 0xf) << 4) | (index3 >> 2); - - const unsigned char index4 = readIndex(); - if (index4 >= INDEX_PAD) //padding - { - assert(index4 == INDEX_PAD); - break; - } - *result++ = ((index3 & 0x3) << 6) | index4; - } - return result; -} -} - -#endif //BASE64_HEADER_08473021856321840873021487213453214 diff --git a/shared/build_info.h b/shared/build_info.h deleted file mode 100644 index f13b2dbc..00000000 --- a/shared/build_info.h +++ /dev/null @@ -1,18 +0,0 @@ -// ************************************************************************** -// * 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 BUILDINFO_H_INCLUDED -#define BUILDINFO_H_INCLUDED - -namespace util -{ -//determine build info -//safer than checking for _WIN64 (defined on windows for 64-bit compilations only) while _WIN32 is always defined (even for x64 compiler!) -static const bool is32BitBuild = sizeof(void*) == 4; -static const bool is64BitBuild = sizeof(void*) == 8; -} - -#endif // BUILDINFO_H_INCLUDED diff --git a/shared/c_dll.h b/shared/c_dll.h deleted file mode 100644 index 15597a9c..00000000 --- a/shared/c_dll.h +++ /dev/null @@ -1,131 +0,0 @@ -// ************************************************************************** -// * 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 C_DLL_HEADER -#define C_DLL_HEADER - -#include <string> -#include <map> -#include <algorithm> - - -namespace c_dll -{ -void writeString(const std::wstring& input, wchar_t* output, size_t outputLen); - - -//Convert handles to objects and vice versa -template <class S, class T> //T: prefer managed object to ensure cleanup if remove() is not called -class HandleProvider -{ -public: - static HandleProvider& instance(); - S insert(T object); - void remove(S handle); - T& retrieve(S handle); //return default-constructed object if not found - -private: - HandleProvider() {} - HandleProvider(const HandleProvider&); - HandleProvider& operator=(const HandleProvider&); - S generate(); - - std::map<S, T> handleMap; -}; -/* -Example: - typedef HandleProvider<TBHandle, ComPtr<ITaskbarList3> > HandleTaskbarMap; - HandleTaskbarMap::instance().insert(xyz); -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//########################## inline implementation ############################# -inline -void writeString(const std::wstring& input, wchar_t* output, size_t outputLen) -{ - if (outputLen > 0) - { - const size_t maxSize = std::min(input.length(), outputLen - 1); - std::copy(input.begin(), input.begin() + maxSize, output); - output[maxSize] = 0; - } -} - - -template <class S, class T> -inline -HandleProvider<S, T>& HandleProvider<S, T>::instance() -{ - static HandleProvider inst; //external linkage!!! :) - return inst; -} - - -//convert handles to objects and vice versa -template <class S, class T> -inline -S HandleProvider<S, T>::insert(T object) -{ - S newHandle = generate(); - handleMap.insert(std::make_pair(newHandle, object)); - return newHandle; -} - - -template <class S, class T> -inline -void HandleProvider<S, T>::remove(S handle) -{ - handleMap.erase(handle); -} - - -template <class S, class T> -inline -T& HandleProvider<S, T>::retrieve(S handle) //return default-constructed object if not found -{ - return handleMap[handle]; -} - - -template <class S, class T> -inline -S HandleProvider<S, T>::generate() -{ - static S handle = 0; - return ++handle; //don't return 0! 0 is reserved for indicating failure -} - - -} - -#endif //C_DLL_HEADER
\ No newline at end of file diff --git a/shared/check_exist.h b/shared/check_exist.h deleted file mode 100644 index 8078d388..00000000 --- a/shared/check_exist.h +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************** -// * 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 CHECKEXIST_H_INCLUDED -#define CHECKEXIST_H_INCLUDED - -#include "zstring.h" -#include "boost_thread_wrap.h" //include <boost/thread.hpp> -#include "file_handling.h" - - -namespace util -{ -//check for file or folder existence asynchronously -boost::unique_future<bool> somethingExistsAsync(const Zstring& somename); -boost::unique_future<bool> fileExistsAsync(const Zstring& filename); -boost::unique_future<bool> dirExistsAsync(const Zstring& dirname); - -//some syntactic sugar: -enum ResultExist -{ - EXISTING_TRUE, - EXISTING_FALSE, - EXISTING_NOT_READY -}; - -ResultExist somethingExists(const Zstring& somename, size_t timeout); -ResultExist fileExists(const Zstring& filename, size_t timeout); -ResultExist dirExists(const Zstring& dirname, size_t timeout); - - - - - - - - - - - - -//################## implementation ########################## -template <bool (*fun)(const Zstring&)> -boost::unique_future<bool> objExistsAsync(const Zstring& objname) -{ - //thread safety: make it a pure value type for use in the thread! - const Zstring objnameVal = objname; //atomic ref-count => binary value-type semantics! - boost::packaged_task<bool> pt([ = ] { return (*fun)(objnameVal); }); - auto fut = pt.get_future(); - boost::thread(std::move(pt)); - return std::move(fut); -} - - -inline -boost::unique_future<bool> somethingExistsAsync(const Zstring& somename) { return objExistsAsync<&zen::somethingExists>(somename); } - -inline -boost::unique_future<bool> fileExistsAsync(const Zstring& filename) { return objExistsAsync<&zen::fileExists>(filename); } - -inline -boost::unique_future<bool> dirExistsAsync(const Zstring& dirname) { return objExistsAsync<&zen::dirExists>(dirname); } - - -template <bool (*fun)(const Zstring&)> inline -ResultExist objExists(const Zstring& objname, size_t timeout) -{ - auto ft = objExistsAsync<fun>(objname); - if (!ft.timed_wait(boost::posix_time::milliseconds(timeout))) - return EXISTING_NOT_READY; - return ft.get() ? EXISTING_TRUE : EXISTING_FALSE; -} - - -inline -ResultExist somethingExists(const Zstring& somename, size_t timeout) { return objExists<&zen::somethingExists>(somename, timeout); } - -inline -ResultExist fileExists(const Zstring& filename, size_t timeout) { return objExists<&zen::fileExists>(filename, timeout); } - -inline -ResultExist dirExists(const Zstring& dirname, size_t timeout) { return objExists<&zen::dirExists>(dirname, timeout); } -} - -#endif // CHECKEXIST_H_INCLUDED diff --git a/shared/com_error.h b/shared/com_error.h deleted file mode 100644 index e3d51d4b..00000000 --- a/shared/com_error.h +++ /dev/null @@ -1,216 +0,0 @@ -// ************************************************************************** -// * 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 COM_ERROR_HEADER -#define COM_ERROR_HEADER - -#include <string> -#include <cstdio> -#include <windows.h> -#undef min -#undef max - -namespace util -{ -std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr); -std::wstring formatWin32Msg(DWORD dwMessageId); //return empty string on error - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//################# implementation ##################### -std::wstring formatWin32Msg(DWORD dwMessageId) //return empty string on error -{ - std::wstring output; - LPWSTR buffer = NULL; - if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_MAX_WIDTH_MASK | - FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0) - { - if (buffer) //just to be sure - { - output = buffer; - ::LocalFree(buffer); - } - } - return output; -} - -namespace -{ -std::wstring formatFacility(HRESULT hr) -{ - switch (HRESULT_FACILITY(hr)) - { - case FACILITY_XPS: - return L"XPS"; - case FACILITY_WINRM: - return L"Windows Resource Manager"; - case FACILITY_WINDOWSUPDATE: - return L"Windows Update"; - case FACILITY_WINDOWS_DEFENDER: - return L"Windows Defender Component"; - case FACILITY_WINDOWS_CE: - return L"Windows CE"; - case FACILITY_WINDOWS: - return L"Windows Subsystem"; - case FACILITY_USERMODE_VOLMGR: - return L"User Mode Volume Manager"; - case FACILITY_USERMODE_VIRTUALIZATION: - return L"User Mode Virtualization Subsystem"; - case FACILITY_USERMODE_VHD: - return L"User Mode Virtual Hard Disk Support"; - case FACILITY_URT: - return L".NET CLR"; - case FACILITY_UMI: - return L"Ubiquitous Memoryintrospection Service"; - case FACILITY_UI: - return L"UI"; - case FACILITY_TPM_SOFTWARE: - return L"Trusted Platform Module Applications"; - case FACILITY_TPM_SERVICES: - return L"Trusted Platform Module Services"; - case FACILITY_SXS: - return L"Side-by-side Servicing"; - case FACILITY_STORAGE: - return L"OLE Storage"; - case FACILITY_STATE_MANAGEMENT: - return L"State Management Services"; - case FACILITY_SCARD: - return L"Smart-card Subsystem"; - case FACILITY_SHELL: - return L"User Shell"; - case FACILITY_SETUPAPI: - return L"Setup API"; - case FACILITY_SECURITY: - return L"Security API Layer"; - case FACILITY_SDIAG: - return L"System Diagnostics"; - case FACILITY_RPC: - return L"RPC Subsystem"; - case FACILITY_RAS: - return L"RAS"; - case FACILITY_PLA: - return L"Performance Logs and Alerts"; - case FACILITY_OPC: - return L"Open Connectivity Service"; - case FACILITY_WIN32: - return L"Win32"; - case FACILITY_CONTROL: - return L"Control Mechanism"; - case FACILITY_WEBSERVICES: - return L"Web Services"; - case FACILITY_NDIS: - return L"Network Driver Interface"; - case FACILITY_METADIRECTORY: - return L"Microsoft Identity Server"; - case FACILITY_MSMQ: - return L"Microsoft Message Queue"; - case FACILITY_MEDIASERVER: - return L"Windows Media Server"; - case FACILITY_MBN: - return L"MBN"; - case FACILITY_INTERNET: - return L"Wininet"; - case FACILITY_ITF: - return L"COM/OLE Interface Management"; - case FACILITY_USERMODE_HYPERVISOR: - return L"Usermode Hypervisor Components"; - case FACILITY_HTTP: - return L"HTTP Support"; - case FACILITY_GRAPHICS: - return L"Graphics Drivers"; - case FACILITY_FWP: - return L"Firewall Platform"; - case FACILITY_FVE: - return L"Full volume encryption"; - case FACILITY_USERMODE_FILTER_MANAGER: - return L"User Mode Filter Manager"; - case FACILITY_DPLAY: - return L"Direct Play"; - case FACILITY_DISPATCH: - return L"COM Dispatch"; - case FACILITY_DIRECTORYSERVICE: - return L"Active Directory"; - case FACILITY_CONFIGURATION: - return L"Configuration Services"; - case FACILITY_COMPLUS: - return L"COM+"; - case FACILITY_USERMODE_COMMONLOG: - return L"Common Logging Support"; - case FACILITY_CMI: - return L"Configuration Management Infrastructure"; - case FACILITY_CERT: - return L"Certificate"; - case FACILITY_BCD: - return L"Boot Configuration Database"; - case FACILITY_BACKGROUNDCOPY: - return L"Background Copy Control"; - case FACILITY_ACS: - return L"Audit Collection Service"; - case FACILITY_AAF: - return L"Microsoft Agent"; - default: - return L"Unknown"; - } -} -} - -inline -std::wstring numberToHexString(long number) -{ - wchar_t result[100]; - ::swprintf(result, 100, L"0x%08x", number); - return std::wstring(result); -} - - -inline -std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr) -{ - std::wstring output(input); - output += L"\n"; - output += L"HRESULT: " + numberToHexString(hr) + L",\n"; - - //don't use _com_error(hr).ErrorMessage(), this is nothing more than a call to ::FormatMessage() - std::wstring win32Msg = formatWin32Msg(hr); - if (!win32Msg.empty()) //empty string on error - output += win32Msg; - else - { - output += L"Facility: " + formatFacility(hr) + L",\n"; - output += L"Win32 Error: " + formatWin32Msg(HRESULT_CODE(hr)); //interpet hr as a Win32 code; this is often useful - } - return output; -} -} -#endif //COM_ERROR_HEADER
\ No newline at end of file diff --git a/shared/com_ptr.h b/shared/com_ptr.h deleted file mode 100644 index be1776fd..00000000 --- a/shared/com_ptr.h +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************** -// * 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 SMART_COM_PTR_H -#define SMART_COM_PTR_H - -#include <Objbase.h> -#include <algorithm> - -namespace util -{ -/* -ComPtr: RAII class handling COM objects - -Example: - -------- - ComPtr<IUPnPDeviceFinder> devFinder; - if (FAILED(::CoCreateInstance(CLSID_UPnPDeviceFinder, - NULL, - CLSCTX_ALL, - IID_PPV_ARGS(devFinder.init())))) - return -1; - - ComPtr<IEnumUnknown> devEnum = com_dynamic_cast<IEnumUnknown>(devColl); - if (!devEnum) - return -1; -*/ - -template <class T> -class ComPtr -{ -public: - ComPtr() : ptr(NULL) {} - - ComPtr(const ComPtr& rhs) : ptr(rhs.ptr) { if (ptr) ptr->AddRef(); } - - ComPtr& operator=(const ComPtr& rhs) - { - ComPtr(rhs).swap(*this); - return *this; - } - - ~ComPtr() { if (ptr) ptr->Release(); } - - T** init() //get pointer for use with ::CoCreateInstance() - { - ComPtr<T>().swap(*this); - return &ptr; - } - - T* get() const { return ptr; } - - T* release() //throw() - { - T* tmp = ptr; - ptr = NULL; - return tmp; - } - - void swap(ComPtr& rhs) { std::swap(ptr, rhs.ptr); } //throw() - - T* operator->() const { return ptr; } - -private: - T* ptr; - - struct ConversionToBool { int dummy; }; -public: - //use member pointer as implicit conversion to bool (C++ Templates - Vandevoorde/Josuttis; chapter 20) - operator int ConversionToBool::* () const { return ptr != NULL ? &ConversionToBool::dummy : NULL; } -}; - - -template <class S, class T> -ComPtr<S> com_dynamic_cast(const ComPtr<T>& other); //throw() - - - - - - - - - - - - - - - - - - - - - - - - - -//################# Inline Implementation ############################# - -//we cannot specialize std::swap() for a class template and are not allowed to overload it => offer swap in own namespace -template <class T> inline -void swap(util::ComPtr<T>& lhs, util::ComPtr<T>& rhs) -{ - lhs.swap(rhs); -} - - -template <class S, class T> inline -ComPtr<S> com_dynamic_cast(const ComPtr<T>& other) //throw() -{ - ComPtr<S> outPtr; - if (other) - other->QueryInterface(IID_PPV_ARGS(outPtr.init())); - return outPtr; -} -} - - -#endif //SMART_COM_PTR_H
\ No newline at end of file diff --git a/shared/com_util.h b/shared/com_util.h deleted file mode 100644 index b8fc777d..00000000 --- a/shared/com_util.h +++ /dev/null @@ -1,133 +0,0 @@ -// ************************************************************************** -// * 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 COM_UTILITY_HEADER -#define COM_UTILITY_HEADER - -#include "com_ptr.h" -#include <string> -#include <cassert> - - -namespace util -{ -//get an enumeration interface as a std::vector of bound(!) ComPtr(s) -template <class T, class U> -std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj); //enumObj: must have the "_NewEnum" property that supports the IEnumUnknown interface - -/* -extract text from com object member function returning a single BSTR: HRESULT ComInterface::MemFun([out] BSTR *pbstr); - Example: ComPtr<...> comObj =...; - std::wstring description = getText(comObj, &IUPnPDevice::get_Description); -*/ -template <class T, class MemFun> -std::wstring getText(ComPtr<T> comObj, MemFun memFun); - - -//RAII class handling BSTR -class Bstring -{ -public: - Bstring(const std::wstring& str) { str_ = ::SysAllocStringLen(str.data(), str.length()); } //string::data() returns unmodified string potentially containing 0-values - ~Bstring() { if (str_) ::SysFreeString(str_); } - - const BSTR get() const { return str_; } - -private: - Bstring(const Bstring&); //not implemented - Bstring& operator=(const Bstring&); // - - BSTR str_; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//############################ inline implemenatation ################################## -template <class T, class U> -inline -std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj) -{ - std::vector<ComPtr<T> > output; - - if (enumObj) - { - ComPtr<IUnknown> unknown; - enumObj->get__NewEnum(unknown.init()); - ComPtr<IEnumUnknown> enumUnknown = com_dynamic_cast<IEnumUnknown>(unknown); - - assert(enumUnknown); //IEnumUnknown must be supported! - if (enumUnknown) - { - ComPtr<IUnknown> itemTmp; - while (enumUnknown->Next(1, itemTmp.init(), NULL) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!! - { - ComPtr<T> itemNew = com_dynamic_cast<T>(itemTmp); - if (itemNew) - output.push_back(itemNew); - } - } - } - - return output; -} - - -template <class T, class MemFun> -inline -std::wstring getText(ComPtr<T> comObj, MemFun memFun) -{ - std::wstring text; - { - if (!comObj) - return std::wstring(); - - BSTR bstr = NULL; - if (FAILED((comObj.get()->*memFun)(&bstr))) - return std::wstring(); - - if (bstr) //NULL means "no text" - { - text = std::wstring(bstr, ::SysStringLen(bstr)); //correctly copy 0-characters - ::SysFreeString(bstr); - } - } - return text; -} -} - - -#endif //COM_UTILITY_HEADER
\ No newline at end of file diff --git a/shared/custom_button.cpp b/shared/custom_button.cpp deleted file mode 100644 index 606db4f2..00000000 --- a/shared/custom_button.cpp +++ /dev/null @@ -1,367 +0,0 @@ -// ************************************************************************** -// * 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 "custom_button.h" -#include <wx/dcmemory.h> -#include <wx/image.h> -#include <algorithm> -#include <limits> -#include <cmath> -#include "image_tools.h" - -using namespace zen; - - -void setBitmapLabel(wxBitmapButton& button, const wxBitmap& bmp) -{ - if (!isEqual(button.GetBitmapLabel(), bmp)) - button.SetBitmapLabel(bmp); -} - - -wxButtonWithImage::wxButtonWithImage(wxWindow* parent, - wxWindowID id, - const wxString& label, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) : - wxBitmapButton(parent, id, wxNullBitmap, pos, size, style | wxBU_AUTODRAW, validator, name), - m_spaceAfter(0), - m_spaceBefore(0) -{ - setTextLabel(label); -} - - -void wxButtonWithImage::setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter) -{ - if (!isEqual(bitmap, bitmapFront) || spaceAfter != m_spaceAfter) //avoid flicker - { - bitmapFront = bitmap; - m_spaceAfter = spaceAfter; - refreshButtonLabel(); - } -} - - -void wxButtonWithImage::setTextLabel(const wxString& text) -{ - if (text != textLabel) //avoid flicker - { - textLabel = text; - wxBitmapButton::SetLabel(text); - refreshButtonLabel(); - } -} - - -void wxButtonWithImage::setBitmapBack(const wxBitmap& bitmap, unsigned spaceBefore) -{ - if (!isEqual(bitmap, bitmapBack) || spaceBefore != m_spaceBefore) //avoid flicker - { - bitmapBack = bitmap; - m_spaceBefore = spaceBefore; - refreshButtonLabel(); - } -} - - -void makeWhiteTransparent(wxImage& image) //assume black text on white background -{ - unsigned char* alphaFirst = image.GetAlpha(); - if (alphaFirst) - { - unsigned char* alphaLast = alphaFirst + image.GetWidth() * image.GetHeight(); - - //dist(black, white) - double distBlackWhite = std::sqrt(3.0 * 255 * 255); - - const unsigned char* bytePos = image.GetData(); - - for (unsigned char* j = alphaFirst; j != alphaLast; ++j) - { - unsigned char r = *bytePos++; // - unsigned char g = *bytePos++; //each pixel consists of three chars - unsigned char b = *bytePos++; // - - //dist((r,g,b), white) - double distColWhite = std::sqrt((255.0 - r) * (255.0 - r) + (255.0 - g) * (255.0 - g) + (255.0 - b) * (255.0 - b)); - - //black(0,0,0) becomes fully opaque(255), while white(255,255,255) becomes transparent(0) - *j = distColWhite / distBlackWhite * wxIMAGE_ALPHA_OPAQUE; - } - } -} - - -wxSize getSizeNeeded(const wxString& text, wxFont& font) -{ - wxCoord width, height; - wxMemoryDC dc; - - wxString textFormatted = text; - textFormatted.Replace(wxT("&"), wxT(""), false); //remove accelerator - dc.GetMultiLineTextExtent(textFormatted, &width, &height , NULL, &font); - return wxSize(width, height); -} - -/* -inline -void linearInterpolationHelper(const int shift, wxImage& img) -{ - unsigned char* const data = img.GetData(); - const int width = img.GetWidth(); - if (width < 2) - return; - - const float intensity = 0.25; - - for (int y = 1; y < img.GetHeight() - 1; ++y) - { - float back = 0; - float middle = 0; - float front = 0; - - unsigned char* location = data + 3 * (y * width) + shift; - const unsigned char* const endPos = location + 3 * width; - - middle = (*location + *(location - 3 * width) + *(location + 3 * width)) / 3;; - front = (*(location + 3) + *(location + 3 * (1 - width)) + *(location + 3 * (1 + width))) / 3; - *location += ((middle + front) / 2 - *location) * intensity; - location += 3; - - while (location < endPos - 3) - { - back = middle; - middle = front; - front = (*(location + 3) + *(location + 3 * (1 - width)) + *(location + 3 * (1 + width))) / 3; - *location += ((back + middle + front) / 3 - *location) * intensity; - location += 3; - } - - back = middle; - middle = front; - *location += ((back + middle) / 2 - *location) * intensity; - } -} - - -void linearInterpolation(wxImage& img) -{ - linearInterpolationHelper(0, img); //red channel - linearInterpolationHelper(1, img); //green channel - linearInterpolationHelper(2, img); //blue channel -} -*/ - - -wxBitmap wxButtonWithImage::createBitmapFromText(const wxString& text) -{ - //wxDC::DrawLabel() doesn't respect alpha channel at all => apply workaround to calculate alpha values manually: - - if (text.empty()) - return wxBitmap(); - - wxFont currentFont = wxBitmapButton::GetFont(); - wxColor textColor = wxBitmapButton::GetForegroundColour(); - - wxSize sizeNeeded = getSizeNeeded(text, currentFont); - wxBitmap newBitmap(sizeNeeded.GetWidth(), sizeNeeded.GetHeight()); - - { - wxMemoryDC dc; - dc.SelectObject(newBitmap); - - //set up white background - dc.SetBackground(*wxWHITE_BRUSH); - dc.Clear(); - - //find position of accelerator - int indexAccel = -1; - size_t accelPos; - wxString textLabelFormatted = text; - if ((accelPos = text.find(wxT("&"))) != wxString::npos) - { - textLabelFormatted.Replace(wxT("&"), wxT(""), false); //remove accelerator - indexAccel = static_cast<int>(accelPos); - } - - dc.SetTextForeground(*wxBLACK); //for use in makeWhiteTransparent - dc.SetTextBackground(*wxWHITE); // - dc.SetFont(currentFont); - - dc.DrawLabel(textLabelFormatted, wxNullBitmap, wxRect(0, 0, newBitmap.GetWidth(), newBitmap.GetHeight()), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, indexAccel); - - dc.SelectObject(wxNullBitmap); - } - - //add alpha channel to image - wxImage finalImage(newBitmap.ConvertToImage()); - finalImage.SetAlpha(); - - //linearInterpolation(finalImage); - - //calculate values for alpha channel - makeWhiteTransparent(finalImage); - - //now apply real text color - unsigned char* bytePos = finalImage.GetData(); - const int pixelCount = finalImage.GetWidth() * finalImage.GetHeight(); - for (int i = 0; i < pixelCount; ++ i) - { - *bytePos++ = textColor.Red(); - *bytePos++ = textColor.Green(); - *bytePos++ = textColor.Blue(); - } - - return wxBitmap(finalImage); -} - - -//copy one image into another, allowing arbitrary overlapping! (pos may contain negative numbers) -void writeToImage(const wxImage& source, const wxPoint pos, wxImage& target) -{ - //determine startpositions in source and target image, as well as width and height to be copied - wxPoint posSrc, posTrg; - int width, height; - - //X-axis - if (pos.x < 0) - { - posSrc.x = -pos.x; - posTrg.x = 0; - width = std::min(pos.x + source.GetWidth(), target.GetWidth()); - } - else - { - posSrc.x = 0; - posTrg.x = pos.x; - width = std::min(target.GetWidth() - pos.x, source.GetWidth()); - } - - //Y-axis - if (pos.y < 0) - { - posSrc.y = -pos.y; - posTrg.y = 0; - height = std::min(pos.y + source.GetHeight(), target.GetHeight()); - } - else - { - posSrc.y = 0; - posTrg.y = pos.y; - height = std::min(target.GetHeight() - pos.y, source.GetHeight()); - } - - - if (width > 0 && height > 0) - { - { - //copy source to target respecting overlapping parts - const unsigned char* sourcePtr = source.GetData() + 3 * (posSrc.x + posSrc.y * source.GetWidth()); - const unsigned char* const sourcePtrEnd = source.GetData() + 3 * (posSrc.x + (posSrc.y + height) * source.GetWidth()); - unsigned char* targetPtr = target.GetData() + 3 * (posTrg.x + posTrg.y * target.GetWidth()); - - while (sourcePtr < sourcePtrEnd) - { - memcpy(targetPtr, sourcePtr, 3 * width); - sourcePtr += 3 * source.GetWidth(); - targetPtr += 3 * target.GetWidth(); - } - } - - //handle different cases concerning alpha channel - if (source.HasAlpha()) - { - if (!target.HasAlpha()) - { - target.SetAlpha(); - unsigned char* alpha = target.GetAlpha(); - memset(alpha, wxIMAGE_ALPHA_OPAQUE, target.GetWidth() * target.GetHeight()); - } - - //copy alpha channel - const unsigned char* sourcePtr = source.GetAlpha() + (posSrc.x + posSrc.y * source.GetWidth()); - const unsigned char* const sourcePtrEnd = source.GetAlpha() + (posSrc.x + (posSrc.y + height) * source.GetWidth()); - unsigned char* targetPtr = target.GetAlpha() + (posTrg.x + posTrg.y * target.GetWidth()); - - while (sourcePtr < sourcePtrEnd) - { - memcpy(targetPtr, sourcePtr, width); - sourcePtr += source.GetWidth(); - targetPtr += target.GetWidth(); - } - } - else if (target.HasAlpha()) - { - unsigned char* targetPtr = target.GetAlpha() + (posTrg.x + posTrg.y * target.GetWidth()); - const unsigned char* const targetPtrEnd = target.GetAlpha() + (posTrg.x + (posTrg.y + height) * target.GetWidth()); - - while (targetPtr < targetPtrEnd) - { - memset(targetPtr, wxIMAGE_ALPHA_OPAQUE, width); - targetPtr += target.GetWidth(); - } - } - } -} - - -namespace -{ -inline -wxSize getSize(const wxBitmap& bmp) -{ - return bmp.IsOk() ? wxSize(bmp.GetWidth(), bmp.GetHeight()) : wxSize(0, 0); -} -} - - -void wxButtonWithImage::refreshButtonLabel() -{ - wxBitmap bitmapText = createBitmapFromText(textLabel); - - wxSize szFront = getSize(bitmapFront); // - wxSize szText = getSize(bitmapText); //make sure to NOT access null-bitmaps! - wxSize szBack = getSize(bitmapBack); // - - //calculate dimensions of new button - const int height = std::max(std::max(szFront.GetHeight(), szText.GetHeight()), szBack.GetHeight()); - const int width = szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore + szBack.GetWidth(); - - //create a transparent image - wxImage transparentImage(width, height, false); - transparentImage.SetAlpha(); - unsigned char* alpha = transparentImage.GetAlpha(); - ::memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, width * height); - - //wxDC::DrawLabel() unfortunately isn't working for transparent images on Linux, so we need to use custom image-concatenation - if (bitmapFront.IsOk()) - writeToImage(bitmapFront.ConvertToImage(), - wxPoint(0, (transparentImage.GetHeight() - bitmapFront.GetHeight()) / 2), - transparentImage); - - if (bitmapText.IsOk()) - writeToImage(bitmapText.ConvertToImage(), - wxPoint(szFront.GetWidth() + m_spaceAfter, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2), - transparentImage); - - if (bitmapBack.IsOk()) - writeToImage(bitmapBack.ConvertToImage(), - wxPoint(szFront.GetWidth() + m_spaceAfter + szText.GetWidth() + m_spaceBefore, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2), - transparentImage); - - //adjust button size - wxSize minSize = GetMinSize(); - - //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly - wxBitmapButton::SetMinSize(wxSize(std::max(width + 10, minSize.GetWidth()), std::max(height + 5, minSize.GetHeight()))); - - //finally set bitmap - wxBitmapButton::SetBitmapLabel(wxBitmap(transparentImage)); -} diff --git a/shared/custom_button.h b/shared/custom_button.h deleted file mode 100644 index 8500e59b..00000000 --- a/shared/custom_button.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************** -// * 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 CUSTOMBUTTON_H_INCLUDED -#define CUSTOMBUTTON_H_INCLUDED - -#include <wx/bmpbuttn.h> - - -//wxButtonWithImage behaves like wxButton but optionally adds bitmap labels -class wxButtonWithImage : public wxBitmapButton -{ -public: - wxButtonWithImage(wxWindow* parent, - wxWindowID id, - const wxString& label, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxButtonNameStr); - - void setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter = 0); - void setTextLabel( const wxString& text); - void setBitmapBack( const wxBitmap& bitmap, unsigned spaceBefore = 0); - -private: - wxBitmap createBitmapFromText(const wxString& text); - void refreshButtonLabel(); - - wxBitmap bitmapFront; - unsigned m_spaceAfter; - wxString textLabel; - unsigned m_spaceBefore; - wxBitmap bitmapBack; -}; - -//set bitmap label flicker free! -void setBitmapLabel(wxBitmapButton& button, const wxBitmap& bmp); - - -#endif // CUSTOMBUTTON_H_INCLUDED diff --git a/shared/custom_tooltip.cpp b/shared/custom_tooltip.cpp deleted file mode 100644 index 0e1c5172..00000000 --- a/shared/custom_tooltip.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// ************************************************************************** -// * 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 "custom_tooltip.h" -#include <wx/stattext.h> -#include <wx/sizer.h> -#include <wx/statbmp.h> -#include <wx/settings.h> - -class CustomTooltip::PopupFrameGenerated : public wxFrame -{ -public: - PopupFrameGenerated(wxWindow* parent, - wxWindowID id = wxID_ANY, - const wxString& title = wxEmptyString, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxSize( -1, -1 ), - long style = wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP | wxSTATIC_BORDER); - - wxStaticText* m_staticTextMain; - wxStaticBitmap* m_bitmapLeft; -}; - - -CustomTooltip::PopupFrameGenerated::PopupFrameGenerated( - wxWindow* parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style ) : wxFrame(parent, id, title, pos, size, style) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white! - this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); // - - wxBoxSizer* bSizer158; - bSizer158 = new wxBoxSizer( wxHORIZONTAL ); - - m_bitmapLeft = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer158->Add( m_bitmapLeft, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticTextMain = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer158->Add( m_staticTextMain, 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5 ); - - this->SetSizer( bSizer158 ); - this->Layout(); - bSizer158->Fit( this ); -} - - -CustomTooltip::CustomTooltip() : tipWindow(new PopupFrameGenerated(NULL)), lastBmp(NULL) -{ -#ifdef FFS_WIN //neither looks good nor works at all on Linux - tipWindow->Disable(); //prevent window stealing focus! -#endif - - hide(); -} - - -CustomTooltip::~CustomTooltip() -{ - tipWindow->Destroy(); -} - - -void CustomTooltip::show(const wxString& text, wxPoint pos, const wxBitmap* bmp) -{ - if (bmp != lastBmp) - { - lastBmp = bmp; - tipWindow->m_bitmapLeft->SetBitmap(bmp == NULL ? wxNullBitmap : *bmp); - } - - if (text != tipWindow->m_staticTextMain->GetLabel()) - { - tipWindow->m_staticTextMain->SetLabel(text); - tipWindow->m_staticTextMain->Wrap(600); - } - -#ifdef FFS_LINUX - tipWindow->Fit(); //Alas Fit() seems to be somewhat broken => this needs to be called EVERY time inside show, not only if text or bmp change. -#endif - - if (pos != tipWindow->GetScreenPosition()) - tipWindow->SetSize(pos.x + 30, pos.y, wxDefaultCoord, wxDefaultCoord); - //attention!!! possible endless loop: mouse pointer must NOT be within tipWindow! - //Else it will trigger a wxEVT_LEAVE_WINDOW which will hide the window, causing the window to be shown again via this method, etc. - - if (!tipWindow->IsShown()) - tipWindow->Show(); -} - - -void CustomTooltip::hide() -{ - tipWindow->Hide(); -} diff --git a/shared/custom_tooltip.h b/shared/custom_tooltip.h deleted file mode 100644 index c68856b4..00000000 --- a/shared/custom_tooltip.h +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************** -// * 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 CUSTOMTOOLTIP_H_INCLUDED -#define CUSTOMTOOLTIP_H_INCLUDED - -#include <wx/frame.h> - -class CustomTooltip -{ -public: - CustomTooltip(); - ~CustomTooltip(); - - void show(const wxString& text, wxPoint pos, const wxBitmap* bmp = NULL); //absolute screen coordinates - void hide(); - -private: - class PopupFrameGenerated; - PopupFrameGenerated* tipWindow; - const wxBitmap* lastBmp; //buffer last used bitmap pointer -}; - -#endif // CUSTOMTOOLTIP_H_INCLUDED diff --git a/shared/debug_log.h b/shared/debug_log.h deleted file mode 100644 index 561eee9d..00000000 --- a/shared/debug_log.h +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************** -// * 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 DEBUG_LOG_HEADER_017324601673246392184621895740256342 -#define DEBUG_LOG_HEADER_017324601673246392184621895740256342 - -#include "zstring.h" -#include <wx/file.h> - - -class DebugLog -{ -public: - wxDEPRECATED(DebugLog(const wxString& filePrefix = wxString())) - prefix(filePrefix), - lineCount(0) - { - logfileName = assembleFileName(); - logFile.Open(logfileName, wxFile::write); - } - - void write(const std::string& logText) - { - todo; - } - - void write(const wxString& logText) - { - ++lineCount; - if (lineCount % 50000 == 0) //prevent logfile from becoming too big - { - logFile.Close(); - wxRemoveFile(logfileName); - - logfileName = assembleFileName(); - logFile.Open(logfileName, wxFile::write); - } - -ersetze wxDateTime::Now() durch eigene lib: - z.b. iso_time.h - - logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ")); - logFile.Write(logText + LINE_BREAK); - } - -private: - wxString assembleFileName() - { - wxString tmp = wxDateTime::Now().FormatISOTime(); - tmp.Replace(wxT(":"), wxEmptyString); - return prefix + wxString(wxT("DEBUG_")) + wxDateTime::Now().FormatISODate() + wxChar('_') + tmp + wxT(".log"); - } - - wxString logfileName; - wxString prefix; - int lineCount; - wxFile logFile; //logFile.close(); <- not needed -}; - -inline DebugLog& globalLogFile() -{ - static DebugLog inst; //external linkage despite header definition! - return inst; -} - -inline wxString getCodeLocation(const wxString& file, int line) -{ - return wxString(file).AfterLast(FILE_NAME_SEPARATOR) + wxT(", LINE ") + toString<wxString>(line) + wxT(" | "); -} - - -//small macro for writing debug information into a logfile -#define WRITE_DEBUG_LOG(x) globalLogFile().write(getCodeLocation(__TFILE__, __LINE__) + x); -//speed alternative: wxLogDebug(wxT("text")) + DebugView - - -#endif //DEBUG_LOG_HEADER_017324601673246392184621895740256342 diff --git a/shared/debug_new.cpp b/shared/debug_new.cpp deleted file mode 100644 index 23a26a4e..00000000 --- a/shared/debug_new.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************** -// * 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 "debug_new.h" - -#ifdef _MSC_VER -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "DbgHelp.h" //available for MSC only -#pragma comment(lib, "Dbghelp.lib") -#endif - - -#ifdef _MSC_VER -namespace -{ -LONG WINAPI writeDumpOnException(EXCEPTION_POINTERS* pExceptionInfo) -{ - HANDLE hFile = ::CreateFile(L"exception.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - MINIDUMP_EXCEPTION_INFORMATION exInfo = {}; - exInfo.ThreadId = ::GetCurrentThreadId(); - exInfo.ExceptionPointers = pExceptionInfo; - exInfo.ClientPointers = NULL; - - MINIDUMP_EXCEPTION_INFORMATION* exceptParam = pExceptionInfo ? &exInfo : NULL; - - ::MiniDumpWriteDump( - ::GetCurrentProcess(), //__in HANDLE hProcess, - ::GetCurrentProcessId(), //__in DWORD ProcessId, - hFile, //__in HANDLE hFile, - MiniDumpWithDataSegs, //__in MINIDUMP_TYPE DumpType, ->Standard: MiniDumpNormal, Medium: MiniDumpWithDataSegs, Full: MiniDumpWithFullMemory - exceptParam, //__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - NULL, //__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - NULL); //__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam - - ::CloseHandle(hFile); - - return EXCEPTION_EXECUTE_HANDLER; -} - - -struct WriteDumpOnUnhandledException -{ - WriteDumpOnUnhandledException() - { - ::SetUnhandledExceptionFilter(writeDumpOnException); - } -} dummy; //ensure that a dump-file is written for uncaught exceptions -} - - -void mem_check::writeMinidump() -{ - writeDumpOnException(NULL); -} - -#endif //_MSC_VER diff --git a/shared/debug_new.h b/shared/debug_new.h deleted file mode 100644 index ba31e489..00000000 --- a/shared/debug_new.h +++ /dev/null @@ -1,97 +0,0 @@ -// ************************************************************************** -// * 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 DEBUGNEW_H_INCLUDED -#define DEBUGNEW_H_INCLUDED - -#include <string> -#include <sstream> -#include <cstdlib> //malloc(), free() - - -#ifndef _MSC_VER -#error currently for use with MSC only -#endif - -/*overwrite "operator new" to get more detailed error messages on bad_alloc, detect memory leaks and write memory dumps -Usage: -- Include everywhere before any other file: $(ProjectDir)\shared\debug_new.h -For Minidumps: -- Compile "debug_new.cpp" -- Compile with debugging symbols and optimization deactivated -*/ - -namespace mem_check -{ -class BadAllocDetailed : public std::bad_alloc -{ -public: - explicit BadAllocDetailed(size_t allocSize) - { - errorMsg = "Memory allocation failed: "; - errorMsg += numberToString(allocSize); - } - - ~BadAllocDetailed() throw() {} - - virtual const char* what() const throw() - { - return errorMsg.c_str(); - } - -private: - template <class T> - static std::string numberToString(const T& number) //convert number to string the C++ way - { - std::ostringstream ss; - ss << number; - return ss.str(); - } - - std::string errorMsg; -}; - -#ifdef _MSC_VER -void writeMinidump(); -#endif -} - -inline -void* operator new(size_t size) -{ - void* newMem = ::malloc(size); - if (!newMem) - { -#ifdef _MSC_VER - mem_check::writeMinidump(); -#endif - throw mem_check::BadAllocDetailed(size); - } - return newMem; -} - - -inline -void operator delete(void* ptr) -{ - ::free(ptr); -} - - -inline -void* operator new[](size_t size) -{ - return operator new(size); -} - - -inline -void operator delete[](void* ptr) -{ - operator delete(ptr); -} - -#endif // DEBUGNEW_H_INCLUDED diff --git a/shared/dir_name.cpp b/shared/dir_name.cpp deleted file mode 100644 index a14367c9..00000000 --- a/shared/dir_name.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// ************************************************************************** -// * 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 "dir_name.h" -#include <wx/dnd.h> -#include <wx/window.h> -#include <wx/textctrl.h> -#include <wx/statbox.h> -#include "file_handling.h" -#include "resolve_path.h" -#include "string_conv.h" -#include "check_exist.h" -#include "util.h" -#include "i18n.h" -#include "folder_history_box.h" - -using namespace zen; - - -namespace -{ -void setDirectoryNameImpl(const wxString& dirname, wxDirPickerCtrl* dirPicker, wxWindow& tooltipWnd, wxStaticBoxSizer* staticBox, size_t timeout) -{ - const wxString dirFormatted = toWx(getFormattedDirectoryName(toZ(dirname))); - - tooltipWnd.SetToolTip(dirFormatted); //wxComboBox bug: the edit control is not updated... hope this will be fixed: http://trac.wxwidgets.org/ticket/12659 - - if (staticBox) - { - //change static box label only if there is a real difference to what is shown in wxTextCtrl anyway - wxString dirNormalized = dirname; - trim(dirNormalized); - if (!dirNormalized.empty() && !endsWith(dirNormalized, FILE_NAME_SEPARATOR)) - dirNormalized += FILE_NAME_SEPARATOR; - - staticBox->GetStaticBox()->SetLabel(dirNormalized == dirFormatted ? wxString(_("Drag && drop")) : dirFormatted); - } - - if (dirPicker) - { - if (!dirFormatted.empty() && - util::dirExists(toZ(dirFormatted), timeout) == util::EXISTING_TRUE) //potentially slow network access: wait 200ms at most - dirPicker->SetPath(dirFormatted); - } -} - - -void setDirectoryName(const wxString& dirname, - wxTextCtrl* txtCtrl, - wxDirPickerCtrl* dirPicker, - wxWindow& tooltipWnd, - wxStaticBoxSizer* staticBox, - size_t timeout = 200) //pointers are optional -{ - if (txtCtrl) - txtCtrl->ChangeValue(dirname); - setDirectoryNameImpl(dirname, dirPicker, tooltipWnd, staticBox, timeout); -} - - -void setDirectoryName(const wxString& dirname, - FolderHistoryBox* comboBox, - wxDirPickerCtrl* dirPicker, - wxWindow& tooltipWnd, - wxStaticBoxSizer* staticBox, - size_t timeout = 200) //pointers are optional -{ - if (comboBox) - comboBox->setValue(dirname); - setDirectoryNameImpl(dirname, dirPicker, tooltipWnd, staticBox, timeout); -} -} -//############################################################################################################## - -template <class NameControl> -DirectoryName<NameControl>::DirectoryName(wxWindow& dropWindow, - wxDirPickerCtrl& dirPicker, - NameControl& dirName, - wxStaticBoxSizer* staticBox, - wxWindow* dropWindow2) : - dropWindow_(dropWindow), - dropWindow2_(dropWindow2), - dirPicker_(dirPicker), - dirName_(dirName), - staticBox_(staticBox) -{ - //prepare drag & drop - setupFileDrop(dropWindow); - if (dropWindow2) - setupFileDrop(*dropWindow2); - - //redirect drag & drop event back to this class - dropWindow.Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this); - if (dropWindow2) - dropWindow2->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this); - - //keep dirPicker and dirName synchronous - dirName_ .Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this); - dirPicker_.Connect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this); -} - - -template <class NameControl> -DirectoryName<NameControl>::~DirectoryName() -{ - dirName_ .Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this); - dirPicker_.Disconnect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this); -} - - -template <class NameControl> -void DirectoryName<NameControl>::OnFilesDropped(FFSFileDropEvent& event) -{ - if (event.getFiles().empty()) - return; - - if (acceptDrop(event.getFiles())) - { - const wxString fileName = event.getFiles()[0]; - if (dirExists(toZ(fileName))) - setDirectoryName(fileName, &dirName_, &dirPicker_, dirName_, staticBox_); - else - { - wxString parentName = beforeLast(fileName, FILE_NAME_SEPARATOR); //returns empty string if ch not found -#ifdef FFS_WIN - if (endsWith(parentName, L":")) //volume name - parentName += FILE_NAME_SEPARATOR; -#endif - if (dirExists(toZ(parentName))) - setDirectoryName(parentName, &dirName_, &dirPicker_, dirName_, staticBox_); - else //set original name unconditionally: usecase: inactive mapped network shares - setDirectoryName(fileName, &dirName_, &dirPicker_, dirName_, staticBox_); - } - } -} - - -template <class NameControl> -void DirectoryName<NameControl>::OnWriteDirManually(wxCommandEvent& event) -{ - setDirectoryName(event.GetString(), static_cast<NameControl*>(NULL), &dirPicker_, dirName_, staticBox_, 100); //potentially slow network access: wait 100 ms at most - event.Skip(); -} - - -template <class NameControl> -void DirectoryName<NameControl>::OnDirSelected(wxFileDirPickerEvent& event) -{ - const wxString newPath = event.GetPath(); - setDirectoryName(newPath, &dirName_, NULL, dirName_, staticBox_); - event.Skip(); -} - - -template <class NameControl> -wxString DirectoryName<NameControl>::getName() const -{ - return dirName_.GetValue(); -} - - -template <class NameControl> -void DirectoryName<NameControl>::setName(const wxString& dirname) -{ - setDirectoryName(dirname, &dirName_, &dirPicker_, dirName_, staticBox_); -} - - -//explicit template instantiation -template class DirectoryName<wxTextCtrl>; -template class DirectoryName<FolderHistoryBox>; diff --git a/shared/dir_name.h b/shared/dir_name.h deleted file mode 100644 index 7c7b3bc4..00000000 --- a/shared/dir_name.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************** -// * 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 DRAGANDDROP_H_INCLUDED -#define DRAGANDDROP_H_INCLUDED - -#include <vector> -#include <wx/event.h> -#include <wx/sizer.h> -#include <wx/filepicker.h> -#include "file_drop.h" - -namespace zen -{ -//handle drag and drop, tooltip, label and manual input, coordinating a wxWindow, wxDirPickerCtrl, and wxComboBox/wxTextCtrl - -template <class NameControl> //NameControl may be wxTextCtrl, FolderHistoryBox -class DirectoryName: private wxEvtHandler -{ -public: - DirectoryName(wxWindow& dropWindow, - wxDirPickerCtrl& dirPicker, - NameControl& dirName, - wxStaticBoxSizer* staticBox = NULL, - wxWindow* dropWindow2 = NULL); //optional - - ~DirectoryName(); - - wxString getName() const; - void setName(const wxString& dirname); - -private: - virtual bool acceptDrop(const std::vector<wxString>& droppedFiles) { return true; }; //return true if drop should be processed - - void OnFilesDropped(FFSFileDropEvent& event); - void OnWriteDirManually(wxCommandEvent& event); - void OnDirSelected(wxFileDirPickerEvent& event); - - const wxWindow& dropWindow_; - const wxWindow* dropWindow2_; - wxDirPickerCtrl& dirPicker_; - NameControl& dirName_; - wxStaticBoxSizer* staticBox_; //optional -}; -} - - -#endif // DRAGANDDROP_H_INCLUDED diff --git a/shared/dir_picker_i18n.h b/shared/dir_picker_i18n.h deleted file mode 100644 index 89b54bf4..00000000 --- a/shared/dir_picker_i18n.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DIR_PICKER_I18N_H_INCLUDED -#define DIR_PICKER_I18N_H_INCLUDED - -#include <wx/filepicker.h> -#include "i18n.h" - - -class FfsDirPickerCtrl : public wxDirPickerCtrl -{ -public: - FfsDirPickerCtrl(wxWindow* parent, wxWindowID id, - const wxString& path = wxEmptyString, - const wxString& message = wxDirSelectorPromptStr, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxDIRP_DEFAULT_STYLE, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxDirPickerCtrlNameStr) : - wxDirPickerCtrl(parent, id, path, message, pos, size, style, validator, name) - { -#ifdef FFS_WIN - //fix wxWidgets localization gap: - wxButton* button = dynamic_cast<wxButton*>(m_pickerIface); - if (button) button->SetLabel(_("Browse")); -#endif - } -}; - - -#endif // DIR_PICKER_I18N_H_INCLUDED diff --git a/shared/dir_watcher.cpp b/shared/dir_watcher.cpp deleted file mode 100644 index 5d178734..00000000 --- a/shared/dir_watcher.cpp +++ /dev/null @@ -1,475 +0,0 @@ -// ************************************************************************** -// * 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 "dir_watcher.h" -#include "last_error.h" -#include "i18n.h" -#include <algorithm> -#include "boost_thread_wrap.h" //include <boost/thread.hpp> -#include "loki/ScopeGuard.h" -#include <set> -#include <wx/log.h> //wxSafeShowMessage - -#ifdef FFS_WIN -#include "notify_removal.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" -#include "privilege.h" - -#elif defined FFS_LINUX -#include <sys/inotify.h> -#include <fcntl.h> -#include "file_traverser.h" -#endif - - -using namespace zen; - -#ifdef FFS_WIN -namespace -{ -class SharedData -{ -public: - //context of worker thread - void addChanges(const char* buffer, DWORD bytesWritten, const Zstring& dirname) //throw () - { - boost::lock_guard<boost::mutex> dummy(lockAccess); - - std::set<Zstring>& output = changedFiles; - - if (bytesWritten == 0) //according to docu this may happen in case of internal buffer overflow: report some "dummy" change - output.insert(L"Overflow!"); - else - { - const char* bufPos = &buffer[0]; - while (true) - { - const FILE_NOTIFY_INFORMATION& notifyInfo = reinterpret_cast<const FILE_NOTIFY_INFORMATION&>(*bufPos); - - const Zstring fullname = dirname + Zstring(notifyInfo.FileName, notifyInfo.FileNameLength / sizeof(WCHAR)); - - //skip modifications sent by changed directories: reason for change, child element creation/deletion, will notify separately! - bool skip = false; - if (notifyInfo.Action == FILE_ACTION_RENAMED_OLD_NAME) //FILE_ACTION_RENAMED_NEW_NAME should suffice - skip = true; - else if (notifyInfo.Action == FILE_ACTION_MODIFIED) - { - //note: this check will not work if top watched directory has been renamed - const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(fullname).c_str()); - bool isDir = ret != INVALID_FILE_ATTRIBUTES && (ret & FILE_ATTRIBUTE_DIRECTORY); //returns true for (dir-)symlinks also - skip = isDir; - } - - if (!skip) - output.insert(fullname); - - if (notifyInfo.NextEntryOffset == 0) - break; - bufPos += notifyInfo.NextEntryOffset; - } - } - } - - //context of main thread - void addChange(const Zstring& dirname) //throw () - { - boost::lock_guard<boost::mutex> dummy(lockAccess); - changedFiles.insert(dirname); - } - - - //context of main thread - void getChanges(std::vector<Zstring>& output) //throw FileError - { - boost::lock_guard<boost::mutex> dummy(lockAccess); - - //first check whether errors occured in thread - if (!errorMsg.empty()) - throw zen::FileError(errorMsg.c_str()); - - output.assign(changedFiles.begin(), changedFiles.end()); - changedFiles.clear(); - } - - - //context of worker thread - void reportError(const std::wstring& msg) //throw () - { - boost::lock_guard<boost::mutex> dummy(lockAccess); - errorMsg = cvrtString<BasicWString>(msg); - } - -private: - typedef Zbase<wchar_t> BasicWString; //thread safe string class for UI texts - - boost::mutex lockAccess; - std::set<Zstring> changedFiles; //get rid of duplicate entries (actually occur!) - BasicWString errorMsg; //non-empty if errors occured in thread -}; - - -class ReadChangesAsync -{ -public: - ReadChangesAsync(const Zstring& directory, //make sure to not leak in thread-unsafe types! - const std::shared_ptr<SharedData>& shared) : - shared_(shared), - dirname(directory) - { - //still in main thread - if (!endsWith(dirname, FILE_NAME_SEPARATOR)) - dirname += FILE_NAME_SEPARATOR; - - //these two privileges are required by ::CreateFile FILE_FLAG_BACKUP_SEMANTICS according to - //http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx - try - { - Privileges::getInstance().ensureActive(SE_BACKUP_NAME); //throw FileError - Privileges::getInstance().ensureActive(SE_RESTORE_NAME); // - } - catch (const FileError&) {} - - hDir = ::CreateFile(applyLongPathPrefix(dirname.c_str()).c_str(), - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - NULL); - if (hDir == INVALID_HANDLE_VALUE ) - throw FileError(_("Could not initialize directory monitoring:") + "\n\"" + utf8CvrtTo<std::wstring>(dirname) + "\"" + "\n\n" + zen::getLastErrorFormatted()); - - //Loki::ScopeGuard guardDir = Loki::MakeGuard(::CloseHandle, hDir); - //guardDir.Dismiss(); - } - - ~ReadChangesAsync() - { - if (hDir != INVALID_HANDLE_VALUE) - ::CloseHandle(hDir); - } - - void operator()() //thread entry - { - try - { - std::vector<char> buffer(64 * 1024); //needs to be aligned on a DWORD boundary; maximum buffer size restricted by some networks protocols (according to docu) - - while (true) - { - boost::this_thread::interruption_point(); - - //actual work - OVERLAPPED overlapped = {}; - overlapped.hEvent = ::CreateEvent(NULL, //__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes, - true, //__in BOOL bManualReset, - false, //__in BOOL bInitialState, - NULL); //__in_opt LPCTSTR lpName - if (overlapped.hEvent == NULL) - return shared_->reportError(_("Error when monitoring directories.") + " (CreateEvent)" + "\n\n" + getLastErrorFormatted()); //throw () + quit thread - - Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, overlapped.hEvent); - (void)dummy; - - //asynchronous variant: runs on this thread's APC queue! - if (!::ReadDirectoryChangesW(hDir, // __in HANDLE hDirectory, - &buffer[0], // __out LPVOID lpBuffer, - static_cast<DWORD>(buffer.size()), // __in DWORD nBufferLength, - true, // __in BOOL bWatchSubtree, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE, // __in DWORD dwNotifyFilter, - NULL, // __out_opt LPDWORD lpBytesReturned, - &overlapped, // __inout_opt LPOVERLAPPED lpOverlapped, - NULL)) // __in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine - return shared_->reportError(_("Error when monitoring directories.") + " (ReadDirectoryChangesW)" + "\n\n" + getLastErrorFormatted()); //throw () + quit thread - - //async I/O is a resource that needs to be guarded since it will write to local variable "buffer"! - Loki::ScopeGuard lockAio = Loki::MakeGuard([&]() - { - //http://msdn.microsoft.com/en-us/library/aa363789(v=vs.85).aspx - if (::CancelIo(hDir) == TRUE) //cancel all async I/O related to this handle and thread - { - DWORD bytesWritten = 0; - ::GetOverlappedResult(hDir, &overlapped, &bytesWritten, true); //wait until cancellation is complete - } - }); - - DWORD bytesWritten = 0; - - //wait for results - while (!::GetOverlappedResult(hDir, //__in HANDLE hFile, - &overlapped, //__in LPOVERLAPPED lpOverlapped, - &bytesWritten, //__out LPDWORD lpNumberOfBytesTransferred, - false)) //__in BOOL bWait - { - if (::GetLastError() != ERROR_IO_INCOMPLETE) - return shared_->reportError(_("Error when monitoring directories.") + " (GetOverlappedResult)" + "\n\n" + getLastErrorFormatted()); //throw () + quit thread - - //execute asynchronous procedure calls (APC) queued on this thread - ::SleepEx(50, // __in DWORD dwMilliseconds, - true); // __in BOOL bAlertable - - boost::this_thread::interruption_point(); - } - lockAio.Dismiss(); - - shared_->addChanges(&buffer[0], bytesWritten, dirname); //throw () - } - } - catch (boost::thread_interrupted&) - { - throw; //this is the only reasonable exception! - } - catch (...) //exceptions must be catched per thread - { - wxSafeShowMessage(wxString(_("An exception occurred!")) + wxT("(Dir Watcher)"), wxT("Unknown exception in worker thread!")); //simple wxMessageBox won't do for threads - } - } - - ReadChangesAsync(ReadChangesAsync && other) : - hDir(INVALID_HANDLE_VALUE) - { - shared_ = std::move(other.shared_); - dirname = std::move(other.dirname); - std::swap(hDir, other.hDir); - } - - HANDLE getDirHandle() const { return hDir; } //for reading purposes only, don't abuse (e.g. close handle)! - -private: - //shared between main and worker: - std::shared_ptr<SharedData> shared_; - //worker thread only: - Zstring dirname; //thread safe! - HANDLE hDir; -}; - - -class HandleVolumeRemoval : public NotifyRequestDeviceRemoval -{ -public: - HandleVolumeRemoval(HANDLE hDir, - boost::thread& worker, - const std::shared_ptr<SharedData>& shared, - const Zstring& dirname) : - NotifyRequestDeviceRemoval(hDir), //throw FileError - worker_(worker), - shared_(shared), - dirname_(dirname), - removalRequested(false), - operationComplete(false) {} - - //all functions are called by main thread! - - bool requestReceived() const { return removalRequested; } - bool finished() const { return operationComplete; } - -private: - virtual void onRequestRemoval(HANDLE hnd) - { - //must release hDir immediately! - worker_.interrupt(); - worker_.join(); - //now hDir should have been released - - //report removal as change to main directory - shared_->addChange(dirname_); - - removalRequested = true; - } //don't throw! - virtual void onRemovalFinished(HANDLE hnd, bool successful) { operationComplete = true; } //throw()! - - boost::thread& worker_; - std::shared_ptr<SharedData> shared_; - Zstring dirname_; - bool removalRequested; - bool operationComplete; -}; -} - - -struct DirWatcher::Pimpl -{ - boost::thread worker; - std::shared_ptr<SharedData> shared; - - std::unique_ptr<HandleVolumeRemoval> volRemoval; -}; - - -DirWatcher::DirWatcher(const Zstring& directory) : //throw FileError - pimpl_(new Pimpl) -{ - pimpl_->shared = std::make_shared<SharedData>(); - - ReadChangesAsync reader(directory, pimpl_->shared); //throw FileError - pimpl_->volRemoval.reset(new HandleVolumeRemoval(reader.getDirHandle(), pimpl_->worker, pimpl_->shared, directory)); //throw FileError - pimpl_->worker = boost::thread(std::move(reader)); -} - - -DirWatcher::~DirWatcher() -{ - pimpl_->worker.interrupt(); - //pimpl_->worker.join(); -> we don't have time to wait... will take ~50ms anyway - //caveat: exitting the app may simply kill this thread! - - //wait until device removal is confirmed, to (hopefully!) prevent locking hDir again by new watch! - if (pimpl_->volRemoval->requestReceived()) - { - const boost::system_time maxwait = boost::get_system_time() + boost::posix_time::seconds(3); //HandleVolumeRemoval::finished() not guaranteed! - - while (!pimpl_->volRemoval->finished() && boost::get_system_time() < maxwait) - boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(50)); - } -} - - -std::vector<Zstring> DirWatcher::getChanges() //throw FileError -{ - std::vector<Zstring> output; - pimpl_->shared->getChanges(output); //throw FileError - return output; -} - - -#elif defined FFS_LINUX -struct DirWatcher::Pimpl -{ - int notifDescr; - std::map<int, Zstring> watchDescrs; //watch descriptor and corresponding directory name (postfixed with separator!) -}; - - -namespace -{ -class DirsOnlyTraverser : public zen::TraverseCallback -{ -public: - DirsOnlyTraverser(std::vector<Zstring>& dirs) : dirs_(dirs) {} - - virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {} - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} - virtual ReturnValDir onDir (const Zchar* shortName, const Zstring& fullName) - { - dirs_.push_back(fullName); - return ReturnValDir(Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_CONTINUE>(), *this); - } - virtual HandleError onError(const std::wstring& errorText) { throw FileError(errorText); } - -private: - std::vector<Zstring>& dirs_; -}; -} - - -DirWatcher::DirWatcher(const Zstring& directory) : //throw FileError - pimpl_(new Pimpl) -{ - //still in main thread - Zstring dirname = directory; - if (endsWith(dirname, FILE_NAME_SEPARATOR)) - dirname.resize(dirname.size() - 1); - - //get all subdirectories - std::vector<Zstring> fullDirList; - fullDirList.push_back(dirname); - - DirsOnlyTraverser traverser(fullDirList); //throw FileError - zen::traverseFolder(dirname, false, traverser); //don't traverse into symlinks (analog to windows build) - - //init - pimpl_->notifDescr = ::inotify_init(); - if (pimpl_->notifDescr == -1) - throw FileError(_("Could not initialize directory monitoring:") + "\n\"" + dirname + "\"" + "\n\n" + getLastErrorFormatted()); - - Loki::ScopeGuard guardDescr = Loki::MakeGuard(::close, pimpl_->notifDescr); - - //set non-blocking mode - bool initSuccess = false; - int flags = ::fcntl(pimpl_->notifDescr, F_GETFL); - if (flags != -1) - initSuccess = ::fcntl(pimpl_->notifDescr, F_SETFL, flags | O_NONBLOCK) != -1; - - if (!initSuccess) - throw FileError(_("Could not initialize directory monitoring:") + "\n\"" + dirname + "\"" + "\n\n" + getLastErrorFormatted()); - - //add watches - std::for_each(fullDirList.begin(), fullDirList.end(), - [&](Zstring subdir) - { - int wd = ::inotify_add_watch(pimpl_->notifDescr, subdir.c_str(), - IN_ONLYDIR | //watch directories only - IN_DONT_FOLLOW | //don't follow symbolic links - IN_MODIFY | - IN_CLOSE_WRITE | - IN_MOVE | - IN_CREATE | - IN_DELETE | - IN_DELETE_SELF | - IN_MOVE_SELF); - if (wd == -1) - throw FileError(_("Could not initialize directory monitoring:") + "\n\"" + subdir + "\"" + "\n\n" + getLastErrorFormatted()); - - if (!endsWith(subdir, FILE_NAME_SEPARATOR)) - subdir += FILE_NAME_SEPARATOR; - pimpl_->watchDescrs.insert(std::make_pair(wd, subdir)); - }); - - guardDescr.Dismiss(); -} - - -DirWatcher::~DirWatcher() -{ - ::close(pimpl_->notifDescr); //associated watches are removed automatically! -} - - -std::vector<Zstring> DirWatcher::getChanges() //throw FileError -{ - std::vector<char> buffer(1024 * (sizeof(struct inotify_event) + 16)); - - //non-blocking call, see O_NONBLOCK - ssize_t bytesRead = ::read(pimpl_->notifDescr, &buffer[0], buffer.size()); - - if (bytesRead == -1) - { - if (errno == EINTR || //Interrupted function call; When this happens, you should try the call again. - errno == EAGAIN) //Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading - return std::vector<Zstring>(); - - throw FileError(_("Error when monitoring directories.") + "\n\n" + getLastErrorFormatted()); - } - - std::set<Zstring> tmp; //get rid of duplicate entries (actually occur!) - - ssize_t bytePos = 0; - while (bytePos < bytesRead) - { - struct inotify_event& evt = reinterpret_cast<struct inotify_event&>(buffer[bytePos]); - - if (evt.len != 0) //exclude case: deletion of "self", already reported by parent directory watch - { - auto iter = pimpl_->watchDescrs.find(evt.wd); - if (iter != pimpl_->watchDescrs.end()) - { - //Note: evt.len is NOT the size of the evt.name c-string, but the array size including all padding 0 characters! - //It may be even 0 in which case evt.name must not be used! - tmp.insert(iter->second + evt.name); - } - } - - bytePos += sizeof(struct inotify_event) + evt.len; - } - - return std::vector<Zstring>(tmp.begin(), tmp.end()); -} - -#endif diff --git a/shared/dir_watcher.h b/shared/dir_watcher.h deleted file mode 100644 index c2bab1d5..00000000 --- a/shared/dir_watcher.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************** -// * 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 DIR_WATCHER_348577025748023458 -#define DIR_WATCHER_348577025748023458 - -#include "file_error.h" -#include <vector> -#include <memory> - -namespace zen -{ -//Windows: ReadDirectoryChangesW http://msdn.microsoft.com/en-us/library/aa365465(v=vs.85).aspx -//Linux: inotify http://linux.die.net/man/7/inotify - -//watch directory including subdirectories -/* -!Note handling of directories!: - Linux: newly added subdirectories are reported but not automatically added for watching! -> reset Dirwatcher! - removal of top watched directory is NOT notified! - Windows: removal of top watched directory also NOT notified (e.g. brute force usb stick removal) - however manual unmount IS notified (e.g. usb stick removal, then re-insert), but watching is stopped! - Renaming of top watched directory handled incorrectly: Not notified(!) + changes in subfolders - report FILE_ACTION_MODIFIED for directory (check that should prevent this fails!) - - Overcome all issues portably: check existence of watched directory externally + reinstall watch after changes in directory structure (added directories) are possible -*/ -class DirWatcher -{ -public: - DirWatcher(const Zstring& directory); //throw FileError - ~DirWatcher(); - - //extract accumulated changes since last call - std::vector<Zstring> getChanges(); //throw FileError - -private: - DirWatcher(const DirWatcher&); - DirWatcher& operator=(const DirWatcher&); - - struct Pimpl; - std::unique_ptr<Pimpl> pimpl_; -}; - -} - -#endif diff --git a/shared/disable_standby.h b/shared/disable_standby.h deleted file mode 100644 index 1a2a2b8a..00000000 --- a/shared/disable_standby.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PREVENTSTANDBY_H_INCLUDED -#define PREVENTSTANDBY_H_INCLUDED - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#endif - -namespace util -{ -class DisableStandby -{ -public: -#ifdef FFS_WIN - DisableStandby() - { - ::SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED /* | ES_AWAYMODE_REQUIRED*/ ); - } - - ~DisableStandby() - { - ::SetThreadExecutionState(ES_CONTINUOUS); - } -#endif -}; -} - -#endif // PREVENTSTANDBY_H_INCLUDED diff --git a/shared/dll_loader.h b/shared/dll_loader.h deleted file mode 100644 index e34fc4a9..00000000 --- a/shared/dll_loader.h +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************** -// * 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 DLLLOADER_H_INCLUDED -#define DLLLOADER_H_INCLUDED - -#include <memory> -#include <string> -#include "loki\ScopeGuard.h" - -#ifdef __WXMSW__ //we have wxWidgets -#include <wx/msw/wrapwin.h> //includes "windows.h" -#else -#include <windows.h> -#undef max -#undef min -#endif - - -namespace util -{ -/* -Manage DLL function and library ownership - - thread safety: like built-in type - - full value semantics - - Usage: - typedef BOOL (WINAPI *IsWow64ProcessFun)(HANDLE hProcess, PBOOL Wow64Process); - const util::DllFun<IsWow64ProcessFun> isWow64Process(L"kernel32.dll", "IsWow64Process"); - if (isWow64Process) -*/ - -template <class Func> -class DllFun -{ -public: - DllFun() : fun(NULL) {} - - DllFun(const wchar_t* libraryName, const char* functionName) : - hLibRef(new HMODULE(::LoadLibrary(libraryName)), deleter), - fun(*hLibRef ? reinterpret_cast<Func>(::GetProcAddress(*hLibRef, functionName)) : NULL) {} - - operator Func() const { return fun; } - -private: - static void deleter(HMODULE* ptr) { if (*ptr) ::FreeLibrary(*ptr); delete ptr; } - - std::shared_ptr<HMODULE> hLibRef; - Func fun; -}; - -/* -extract binary resources from .exe/.dll: - --- resource.h -- -#define MY_BINARY_RESOURCE 1337 - --- resource.rc -- -MY_BINARY_RESOURCE RCDATA "filename.dat" -*/ -std::string getResourceStream(const std::wstring& libraryName, size_t resourceId); - - - - - - - - - - - - - - - - -//---------------Inline Implementation--------------------------------------------------- -inline -std::string getResourceStream(const wchar_t* libraryName, size_t resourceId) -{ - std::string output; - HMODULE module = ::LoadLibrary(libraryName); - if (module) - { - LOKI_ON_BLOCK_EXIT2(::FreeLibrary(module)); - - const HRSRC res = ::FindResource(module, MAKEINTRESOURCE(resourceId), RT_RCDATA); - if (res != NULL) - { - const HGLOBAL resHandle = ::LoadResource(module, res); - if (resHandle != NULL) - { - const char* stream = static_cast<const char*>(::LockResource(resHandle)); - if (stream) - { - const DWORD streamSize = ::SizeofResource(module, res); - output.assign(stream, streamSize); - } - } - } - } - return output; -} -} - -#endif // DLLLOADER_H_INCLUDED diff --git a/shared/dst_hack.cpp b/shared/dst_hack.cpp deleted file mode 100644 index aa7a0f3e..00000000 --- a/shared/dst_hack.cpp +++ /dev/null @@ -1,387 +0,0 @@ -#include "dst_hack.h" -#include "i18n.h" -#include "long_path_prefix.h" -#include "string_utf8.h" -#include "last_error.h" -#include "assert_static.h" -#include <bitset> -#include "global_func.h" -#include <limits> -#include "int64.h" -#include "file_error.h" -#include "dll_loader.h" - -using namespace zen; - - -namespace -{ -//fast ::GetVolumePathName() clone: let's hope it's not too simple (doesn't honor mount points) -Zstring getVolumeName(const Zstring& filename) -{ - //this call is expensive: ~1.5 ms! - // if (!::GetVolumePathName(applyLongPathPrefix(filename).c_str(), //__in LPCTSTR lpszFileName, - // fsName, //__out LPTSTR lpszVolumePathName, - // BUFFER_SIZE)) //__in DWORD cchBufferLength - // ... - // Zstring volumePath = fsName; - // if (!volumePath.EndsWith(FILE_NAME_SEPARATOR)) //a trailing backslash is required - // volumePath += FILE_NAME_SEPARATOR; - - Zstring nameFmt = removeLongPathPrefix(filename); //throw() - if (!endsWith(nameFmt, FILE_NAME_SEPARATOR)) - nameFmt += FILE_NAME_SEPARATOR; //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; - } - return 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 Zstring(nameFmt.c_str(), 3); - } - - return Zstring(); -} -} - - -bool dst::isFatDrive(const Zstring& fileName) //throw() -{ - const size_t BUFFER_SIZE = MAX_PATH + 1; - wchar_t fsName[BUFFER_SIZE]; - - const Zstring volumePath = getVolumeName(fileName); - if (volumePath.empty()) - return false; - - //suprisingly fast: ca. 0.03 ms per call! - if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - NULL, //__out LPTSTR lpVolumeNameBuffer, - 0, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - fsName, //__out LPTSTR lpFileSystemNameBuffer, - BUFFER_SIZE)) //__in DWORD nFileSystemNameSize - { - assert(false); //shouldn't happen - return false; - } - //DST hack seems to be working equally well for FAT and FAT32 (in particular creation time has 10^-2 s precision as advertised) - return fsName == Zstring(L"FAT") || - fsName == Zstring(L"FAT32"); -} - - -bool dst::vistaOrLater() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - //IFileOperation is supported with Vista and later - if (::GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5; - //XP has majorVersion == 5, minorVersion == 1 - //Vista has majorVersion == 6, minorVersion == 0 - //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} - - -bool dst::isFatDrive(HANDLE hFile) //throw() -{ - //dynamically load windows API function - typedef BOOL (WINAPI *GetVolumeInformationByHandleWFunc)(HANDLE hFile, - LPWSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPWSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize); - - const util::DllFun<GetVolumeInformationByHandleWFunc> getVolumeInformationByHandle(L"kernel32.dll", "GetVolumeInformationByHandleW"); - if (!getVolumeInformationByHandle) - { - assert(false); - return false; - } - - const size_t BUFFER_SIZE = MAX_PATH + 1; - wchar_t fsName[BUFFER_SIZE]; - - if (!getVolumeInformationByHandle(hFile, //__in HANDLE hFile, - NULL, //__out LPTSTR lpVolumeNameBuffer, - 0, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - fsName, //__out LPTSTR lpFileSystemNameBuffer, - BUFFER_SIZE)) //__in DWORD nFileSystemNameSize - { - assert(false); //shouldn't happen - return false; - } - //DST hack seems to be working equally well for FAT and FAT32 (in particular creation time has 10^-2 s precision as advertised) - return fsName == Zstring(L"FAT") || - fsName == Zstring(L"FAT32"); -} - - -namespace -{ -//convert UInt64 and Int64 to FILETIME -inline -FILETIME toFiletime(Int64 number) -{ - const UInt64 unsig = to<UInt64>(number); - - FILETIME output = {}; - output.dwLowDateTime = unsig.getLo(); - output.dwHighDateTime = unsig.getHi(); - return output; -} - -FILETIME toFiletime(UInt64 number) -{ - FILETIME output = {}; - output.dwLowDateTime = number.getLo(); - output.dwHighDateTime = number.getHi(); - return output; -} - -inline -UInt64 toUInt64(const FILETIME& fileTime) -{ - return UInt64(fileTime.dwLowDateTime, fileTime.dwHighDateTime); -} - - -inline -Int64 toInt64(const FILETIME& fileTime) -{ - return to<Int64>(UInt64(fileTime.dwLowDateTime, fileTime.dwHighDateTime)); -} - - -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 - { - const std::wstring errorMessage = _("Conversion error:") + " FILETIME -> local FILETIME: " + "(" + - "High: " + toString<std::wstring>(utcTime.dwHighDateTime) + " " + - "Low: " + toString<std::wstring>(utcTime.dwLowDateTime) + ") " + "\n\n" + getLastErrorFormatted(); - throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); - } - return localTime; -} - - -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 - { - const std::wstring errorMessage = _("Conversion error:") + " local FILETIME -> FILETIME: " + "(" + - "High: " + toString<std::wstring>(localTime.dwHighDateTime) + " " + - "Low: " + toString<std::wstring>(localTime.dwLowDateTime) + ") " + "\n\n" + getLastErrorFormatted(); - throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); - } - return utcTime; -} - - -//struct FILETIME {DWORD dwLowDateTime; DWORD dwHighDateTime;}; -const FILETIME FAT_MIN_TIME = { 13374976, 27846544 }; //1980 \ both are valid max/min FAT dates for 2 second precision -const FILETIME FAT_MAX_TIME = { 14487552, 37251238 }; //2107 / - -//http://en.wikipedia.org/wiki/File_Allocation_Table -const size_t PRECISION_WRITE_TIME = 20000000; //number of 100 ns per step -> 2 s -const size_t PRECISION_CREATE_TIME = 100000; // -> 1/100 s - -/* -Number of bits of information in create time: ln_2((FAT_MAX_TIME - FAT_MIN_TIME) / PRECISION_CREATE_TIME) = 38.55534023 -Number of bits of information in write time: 30.91148404 -*/ -//total size available to store data: -const size_t CREATE_TIME_INFO_BITS = 38; -// I. indicator that offset in II) is present -const size_t INDICATOR_EXISTING_BITS = 1; -// II. local<->UTC time offset -const size_t UTC_LOCAL_OFFSET_BITS = 7; -// III. indicator that offset in II) corresponds to current local write time (this could be a hash of the write time) -const size_t WRITE_TIME_HASH_BITS = CREATE_TIME_INFO_BITS - INDICATOR_EXISTING_BITS - UTC_LOCAL_OFFSET_BITS; - - -template <size_t precision> -FILETIME encodeRawInformation(UInt64 rawInfo) -{ - rawInfo *= precision; - rawInfo += toUInt64(FAT_MIN_TIME); - - assert(rawInfo <= toUInt64(FAT_MAX_TIME)); - return toFiletime(rawInfo); -} - - -template <size_t precision> -UInt64 extractRawInformation(const FILETIME& createTime) -{ - assert(toUInt64(FAT_MIN_TIME) <= toUInt64(createTime)); - assert(toUInt64(createTime) <= toUInt64(FAT_MAX_TIME)); - - //FAT create time ranges from 1980 - 2107 (2^7 years) with 1/100 seconds precision - UInt64 rawInfo = toUInt64(createTime); - - rawInfo -= toUInt64(FAT_MIN_TIME); - rawInfo /= precision; //reduce precision (FILETIME has unit 10^-7 s) - - assert(toUInt64(encodeRawInformation<precision>(rawInfo)) == toUInt64(createTime)); //must be reversible - return rawInfo; -} - - -//convert write time to it's minimal representation (no restriction to FAT range "1980 - 2107") -UInt64 extractRawWriteTime(const FILETIME& writeTime) -{ - UInt64 rawInfo = toUInt64(writeTime); - assert(rawInfo % PRECISION_WRITE_TIME == 0U); - rawInfo /= PRECISION_WRITE_TIME; //reduce precision (FILETIME has unit 10^-7 s) - return rawInfo; -} - - -//files with different resolution than 2 seconds are rounded up when written to FAT -FILETIME roundToFatWriteTime(const FILETIME& writeTime) -{ - UInt64 rawData = toUInt64(writeTime); - - if (rawData % PRECISION_WRITE_TIME != 0U) - rawData += PRECISION_WRITE_TIME; - - rawData /= PRECISION_WRITE_TIME; - rawData *= PRECISION_WRITE_TIME; - return toFiletime(rawData); -} - - -//get 7-bit value representing time shift in number of quarter-hours -std::bitset<UTC_LOCAL_OFFSET_BITS> getUtcLocalShift() -{ - FILETIME utcTime = FAT_MIN_TIME; - utcTime.dwHighDateTime += 5000000; //some arbitrary valid time - - const FILETIME localTime = utcToLocal(utcTime); - - const int timeShiftSec = to<int>((toInt64(localTime) - toInt64(utcTime)) / 10000000); //time shift in seconds - - const int timeShiftQuarter = timeShiftSec / (60 * 15); //time shift in quarter-hours - - 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! - { - const std::wstring errorMessage = _("Conversion error:") + " Unexpected UTC <-> local time shift: " + - "(" + toString<std::wstring>(timeShiftSec) + ") " + "\n\n" + getLastErrorFormatted(); - throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); - } - - std::bitset<UTC_LOCAL_OFFSET_BITS> output(absValue); - output[UTC_LOCAL_OFFSET_BITS - 1] = timeShiftQuarter < 0; //sign bit - return output; -} - - -//get time-zone shift in seconds -inline -int convertUtcLocalShift(std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift) -{ - const bool hasSign = rawShift[UTC_LOCAL_OFFSET_BITS - 1]; - rawShift[UTC_LOCAL_OFFSET_BITS - 1] = false; - - assert_static(UTC_LOCAL_OFFSET_BITS <= sizeof(unsigned long) * 8); - return hasSign ? - static_cast<int>(rawShift.to_ulong()) * 15 * 60 * -1 : - static_cast<int>(rawShift.to_ulong()) * 15 * 60; -} -} - - -bool dst::fatHasUtcEncoded(const RawTime& rawTime) //"createTimeRaw" as retrieved by ::FindFirstFile() and ::GetFileAttributesEx(); throw (std::runtime_error) -{ - if (toUInt64(rawTime.createTimeRaw) < toUInt64(FAT_MIN_TIME) || - toUInt64(FAT_MAX_TIME) < toUInt64(rawTime.createTimeRaw)) - { - assert(false); //shouldn't be possible according to FAT specification - return false; - } - - const UInt64 rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw)); - - assert_static(WRITE_TIME_HASH_BITS == 30); - return (extractRawWriteTime(utcToLocal(rawTime.writeTimeRaw)) & 0x3FFFFFFFU) == (rawInfo & 0x3FFFFFFFU) && //ensure write time wasn't changed externally - rawInfo >> (CREATE_TIME_INFO_BITS - INDICATOR_EXISTING_BITS) == 1U; //extended data available -} - - -dst::RawTime dst::fatEncodeUtcTime(const FILETIME& writeTimeRealUtc) //throw (std::runtime_error) -{ - const FILETIME fatWriteTimeUtc = roundToFatWriteTime(writeTimeRealUtc); //writeTimeRealUtc may have incompatible precision (NTFS) - - //create time lets us store 40 bit of information - - //indicator that utc time is encoded -> hopefully results in a date long way in the future; but even if this bit is accidentally set, we still have the hash! - UInt64 data = 1U; - - const std::bitset<UTC_LOCAL_OFFSET_BITS> utcShift = getUtcLocalShift(); - data <<= UTC_LOCAL_OFFSET_BITS; - data |= utcShift.to_ulong(); - - data <<= WRITE_TIME_HASH_BITS; - data |= extractRawWriteTime(utcToLocal(fatWriteTimeUtc)) & 0x3FFFFFFFU; //trim to last 30 bit of information - assert_static(WRITE_TIME_HASH_BITS == 30); - - const FILETIME encodedData = localToUtc(encodeRawInformation<PRECISION_CREATE_TIME>(data)); //localToUtc: make sure data is physically saved as FAT local time - assert(toUInt64(FAT_MIN_TIME) <= toUInt64(encodedData)); - assert(toUInt64(encodedData) <= toUInt64(FAT_MAX_TIME)); - - return RawTime(encodedData, fatWriteTimeUtc); //keep compatible with other applications, at least until DST shift actually occurs -} - - -FILETIME dst::fatDecodeUtcTime(const RawTime& rawTime) //return real UTC time; throw (std::runtime_error) -{ - if (!fatHasUtcEncoded(rawTime)) - return rawTime.writeTimeRaw; - - const UInt64 rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw)); - - const std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift(to<int>((rawInfo >> WRITE_TIME_HASH_BITS) & 0x7FU)); //static_cast<int>: a shame MSC... "unsigned long" should be supported instead! - assert_static(UTC_LOCAL_OFFSET_BITS == 7); - - const int timeShiftSec = convertUtcLocalShift(rawShift); - const FILETIME writeTimeLocal = utcToLocal(rawTime.writeTimeRaw); - - const Int64 realUTC = toInt64(writeTimeLocal) - Int64(timeShiftSec) * 10000000; - return toFiletime(realUTC); -} diff --git a/shared/dst_hack.h b/shared/dst_hack.h deleted file mode 100644 index 2e25cf81..00000000 --- a/shared/dst_hack.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef DST_HACK_H_INCLUDED -#define DST_HACK_H_INCLUDED - -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "zstring.h" -#include <stdexcept> - - -namespace dst -{ -/* -Solve DST +-1h and time zone shift issues on FAT drives -------------------------------------------------------- -- (local) last write time is not touched! -- all additional metadata is encoded in local create time: - I. indicator that offset in II) is present - II. local<->UTC time offset - III. indicator that offset in II) corresponds to current local write time (a hash of local last write time) -*/ - -bool isFatDrive(const Zstring& fileName); //throw () -bool isFatDrive(HANDLE hFile); //throw() -> call ONLY if vistaOrLater() == true! -bool vistaOrLater(); - -//all subsequent functions may throw the std::runtime_error exception! - -struct RawTime //time as retrieved by ::FindFirstFile() and ::GetFileAttributesEx() -{ - RawTime(const FILETIME& create, const FILETIME& lastWrite) : createTimeRaw(create), writeTimeRaw(lastWrite) {} - FILETIME createTimeRaw; - FILETIME writeTimeRaw; -}; -//save UTC time resistant against DST/time zone shifts -bool fatHasUtcEncoded(const RawTime& rawTime); //as retrieved by ::FindFirstFile() and ::GetFileAttributesEx(); throw (std::runtime_error) - -RawTime fatEncodeUtcTime(const FILETIME& writeTimeRealUtc); //throw (std::runtime_error) -FILETIME fatDecodeUtcTime(const RawTime& rawTime); //return last write time in real UTC; throw (std::runtime_error) -} - -#endif // DST_HACK_H_INCLUDED diff --git a/shared/file_drop.h b/shared/file_drop.h deleted file mode 100644 index 8b11ccfb..00000000 --- a/shared/file_drop.h +++ /dev/null @@ -1,113 +0,0 @@ -// ************************************************************************** -// * 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 FILE_DROP_H_INCLUDED -#define FILE_DROP_H_INCLUDED - -#include <wx/event.h> -#include <wx/dnd.h> - -namespace zen -{ -//register simple file drop event (without issue of freezing dialogs and without wxFileDropTarget overdesign) - -//1. have a window emit FFS_DROP_FILE_EVENT -void setupFileDrop(wxWindow& wnd); - -//2. register events: -//wnd.Connect (FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(MyDlg::OnFilesDropped), NULL, this); -//wnd.Disconnect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(MyDlg::OnFilesDropped), NULL, this); - -//3. do something: -//void MyDlg::OnFilesDropped(FFSFileDropEvent& event); - - - - - - - - - - - - - - - - - -inline -wxEventType createNewEventType() -{ - //inline functions have external linkage by default => this static is also extern, i.e. program wide unique! but defined in a header... ;) - static wxEventType dummy = wxNewEventType(); - return dummy; -} - -//define new event type -const wxEventType FFS_DROP_FILE_EVENT = createNewEventType(); - -class FFSFileDropEvent : public wxCommandEvent -{ -public: - FFSFileDropEvent(const std::vector<wxString>& filesDropped, const wxWindow& dropWindow, wxPoint dropPos) : - wxCommandEvent(FFS_DROP_FILE_EVENT), - filesDropped_(filesDropped), - dropWindow_(dropWindow), - dropPos_(dropPos) {} - - virtual wxEvent* Clone() const - { - return new FFSFileDropEvent(filesDropped_, dropWindow_, dropPos_); - } - - const std::vector<wxString>& getFiles() const { return filesDropped_; } - const wxWindow& getDropWindow() const { return dropWindow_; } - wxPoint getDropPosition() const { return dropPos_; } //position relative to drop window - -private: - const std::vector<wxString> filesDropped_; - const wxWindow& dropWindow_; - wxPoint dropPos_; -}; - -typedef void (wxEvtHandler::*FFSFileDropEventFunction)(FFSFileDropEvent&); - -#define FFSFileDropEventHandler(func) \ - (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(FFSFileDropEventFunction, &func) - - -class WindowDropTarget : public wxFileDropTarget -{ -public: - WindowDropTarget(wxWindow& dropWindow) : dropWindow_(dropWindow) {} - - virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& fileArray) - { - std::vector<wxString> filenames(fileArray.begin(), fileArray.end()); - if (!filenames.empty()) - { - //create a custom event on drop window: execute event after file dropping is completed! (after mouse is released) - FFSFileDropEvent evt(filenames, dropWindow_, wxPoint(x, y)); - dropWindow_.GetEventHandler()->AddPendingEvent(evt); - } - return true; - } - -private: - wxWindow& dropWindow_; -}; - - -inline -void setupFileDrop(wxWindow& wnd) -{ - wnd.SetDropTarget(new WindowDropTarget(wnd)); //takes ownership -} -} - -#endif // FILE_DROP_H_INCLUDED diff --git a/shared/file_error.h b/shared/file_error.h deleted file mode 100644 index d814e05d..00000000 --- a/shared/file_error.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************** -// * 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 FILEERROR_H_INCLUDED -#define FILEERROR_H_INCLUDED - -#include "zstring.h" -#include "string_utf8.h" -#include <string> - - -namespace zen -{ -class FileError //Exception base class used to notify file/directory copy/delete errors -{ -public: - FileError(const std::wstring& message) : errorMessage(message) {} - virtual ~FileError() {} - - const std::wstring& msg() const { return errorMessage; } - -private: - std::wstring errorMessage; -}; - -#define DEFINE_NEW_FILE_ERROR(X) struct X : public FileError { X(const std::wstring& message) : FileError(message) {} }; - -DEFINE_NEW_FILE_ERROR(ErrorNotExisting); -DEFINE_NEW_FILE_ERROR(ErrorTargetExisting); -DEFINE_NEW_FILE_ERROR(ErrorTargetPathMissing); -DEFINE_NEW_FILE_ERROR(ErrorFileLocked); - - - -//----------- facilitate usage of std::wstring for error messages -------------------- - -//allow implicit UTF8 conversion: since std::wstring models a GUI string, convenience is more important than performance -inline std::wstring operator+(const std::wstring& lhs, const Zstring& rhs) { return std::wstring(lhs) += zen::utf8CvrtTo<std::wstring>(rhs); } - -//we musn't put our overloads in namespace std, but namespace zen (+ using directive) is sufficient -inline std::wstring operator+(const std::wstring& lhs, const char* rhs) { return std::wstring(lhs) += utf8CvrtTo<std::wstring>(rhs); } -inline std::wstring operator+(const std::wstring& lhs, const std::string& rhs) { return std::wstring(lhs) += utf8CvrtTo<std::wstring>(rhs); } -} - -#endif // FILEERROR_H_INCLUDED diff --git a/shared/file_handling.cpp b/shared/file_handling.cpp deleted file mode 100644 index c9e85c15..00000000 --- a/shared/file_handling.cpp +++ /dev/null @@ -1,2075 +0,0 @@ -// ************************************************************************** -// * 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 "file_handling.h" -#include <map> -#include <algorithm> -#include <stdexcept> -#include "last_error.h" -#include "file_traverser.h" -#include "loki/ScopeGuard.h" -#include "symlink_target.h" -#include "file_io.h" -#include "i18n.h" -#include "assert_static.h" -#include <boost/thread/tss.hpp> -#include <boost/thread/once.hpp> -#include "file_id_internal.h" - -#ifdef FFS_WIN -#include "privilege.h" -#include "dll_loader.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" -#include <Aclapi.h> -#include "dst_hack.h" -#include "file_update_handle.h" - -#elif defined FFS_LINUX -#include <sys/stat.h> -#include <time.h> -#include <utime.h> -#include <cerrno> -#include <sys/time.h> - -#ifdef HAVE_SELINUX -#include <selinux/selinux.h> -#endif -#endif - -using namespace zen; - - -bool zen::fileExists(const Zstring& filename) -{ - //symbolic links (broken or not) are also treated as existing files! -#ifdef FFS_WIN - const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(filename).c_str()); - return ret != INVALID_FILE_ATTRIBUTES && !(ret & FILE_ATTRIBUTE_DIRECTORY); //returns true for (file-)symlinks also - -#elif defined FFS_LINUX - struct stat fileInfo = {}; - return ::lstat(filename.c_str(), &fileInfo) == 0 && - (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode)); //in Linux a symbolic link is neither file nor directory -#endif -} - - -bool zen::dirExists(const Zstring& dirname) -{ - //symbolic links (broken or not) are also treated as existing directories! -#ifdef FFS_WIN - const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str()); - return ret != INVALID_FILE_ATTRIBUTES && (ret & FILE_ATTRIBUTE_DIRECTORY); //returns true for (dir-)symlinks also - -#elif defined FFS_LINUX - struct stat dirInfo = {}; - return ::lstat(dirname.c_str(), &dirInfo) == 0 && - (S_ISLNK(dirInfo.st_mode) || S_ISDIR(dirInfo.st_mode)); //in Linux a symbolic link is neither file nor directory -#endif -} - - -bool zen::symlinkExists(const Zstring& objname) -{ -#ifdef FFS_WIN - const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(objname).c_str()); - return ret != INVALID_FILE_ATTRIBUTES && (ret & FILE_ATTRIBUTE_REPARSE_POINT); - -#elif defined FFS_LINUX - struct stat fileInfo = {}; - return ::lstat(objname.c_str(), &fileInfo) == 0 && - S_ISLNK(fileInfo.st_mode); //symbolic link -#endif -} - - -bool zen::somethingExists(const Zstring& objname) //throw() check whether any object with this name exists -{ -#ifdef FFS_WIN - return ::GetFileAttributes(applyLongPathPrefix(objname).c_str()) != INVALID_FILE_ATTRIBUTES; - -#elif defined FFS_LINUX - struct stat fileInfo = {}; - return ::lstat(objname.c_str(), &fileInfo) == 0; -#endif -} - - -namespace -{ -void getFileAttrib(const Zstring& filename, FileAttrib& attr, ProcSymlink procSl) //throw FileError -{ -#ifdef FFS_WIN - WIN32_FIND_DATA fileInfo = {}; - { - const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(filename).c_str(), &fileInfo); - if (searchHandle == INVALID_HANDLE_VALUE) - throw FileError(_("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - ::FindClose(searchHandle); - } - // WIN32_FILE_ATTRIBUTE_DATA sourceAttr = {}; - // if (!::GetFileAttributesEx(applyLongPathPrefix(sourceObj).c_str(), //__in LPCTSTR lpFileName, - // GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId, - // &sourceAttr)) //__out LPVOID lpFileInformation - - const bool isSymbolicLink = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0; - if (!isSymbolicLink || procSl == SYMLINK_DIRECT) - { - //####################################### DST hack ########################################### - const bool isDirectory = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - if (!isDirectory && dst::isFatDrive(filename)) //throw() - { - const dst::RawTime rawTime(fileInfo.ftCreationTime, fileInfo.ftLastWriteTime); - if (dst::fatHasUtcEncoded(rawTime)) //throw (std::runtime_error) - { - fileInfo.ftLastWriteTime = dst::fatDecodeUtcTime(rawTime); //return last write time in real UTC, throw (std::runtime_error) - ::GetSystemTimeAsFileTime(&fileInfo.ftCreationTime); //real creation time information is not available... - } - } - //####################################### DST hack ########################################### - - attr.fileSize = UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh); - attr.modificationTime = toTimeT(fileInfo.ftLastWriteTime); - } - else - { - const HANDLE hFile = ::CreateFile(applyLongPathPrefix(filename).c_str(), //open handle to target of symbolic link - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - throw FileError(_("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hFile)); - - BY_HANDLE_FILE_INFORMATION fileInfoHnd = {}; - if (!::GetFileInformationByHandle(hFile, &fileInfoHnd)) - throw FileError(_("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - - attr.fileSize = UInt64(fileInfoHnd.nFileSizeLow, fileInfoHnd.nFileSizeHigh); - attr.modificationTime = toTimeT(fileInfoHnd.ftLastWriteTime); - } - -#elif defined FFS_LINUX - struct stat fileInfo = {}; - - const int rv = procSl == SYMLINK_FOLLOW ? - :: stat(filename.c_str(), &fileInfo) : - ::lstat(filename.c_str(), &fileInfo); - if (rv != 0) //follow symbolic links - throw FileError(_("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - - attr.fileSize = UInt64(fileInfo.st_size); - attr.modificationTime = fileInfo.st_mtime; -#endif -} -} - - -UInt64 zen::getFilesize(const Zstring& filename) //throw FileError -{ - FileAttrib attr; - getFileAttrib(filename, attr, SYMLINK_FOLLOW); //throw FileError - return attr.fileSize; -} - - -Int64 zen::getFileTime(const Zstring& filename, ProcSymlink procSl) //throw FileError -{ - FileAttrib attr; - getFileAttrib(filename, attr, procSl); //throw FileError - return attr.modificationTime; -} - - -namespace -{ - - -#ifdef FFS_WIN -DWORD retrieveVolumeSerial(const Zstring& pathName) //return 0 on error! -{ - std::vector<wchar_t> buffer(10000); - - //full pathName need not yet exist! - if (!::GetVolumePathName(pathName.c_str(), //__in LPCTSTR lpszFileName, - &buffer[0], //__out LPTSTR lpszVolumePathName, - static_cast<DWORD>(buffer.size()))) //__in DWORD cchBufferLength - return 0; - - Zstring volumePath = &buffer[0]; - if (!volumePath.EndsWith(FILE_NAME_SEPARATOR)) - volumePath += FILE_NAME_SEPARATOR; - - DWORD volumeSerial = 0; - if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - NULL, //__out LPTSTR lpVolumeNameBuffer, - 0, //__in DWORD nVolumeNameSize, - &volumeSerial, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, - 0)) //__in DWORD nFileSystemNameSize - return 0; - - return volumeSerial; -} -#elif defined FFS_LINUX - -dev_t retrieveVolumeSerial(const Zstring& pathName) //return 0 on error! -{ - Zstring volumePathName = pathName; - - //remove trailing slash - if (volumePathName.size() > 1 && volumePathName.EndsWith(FILE_NAME_SEPARATOR)) //exception: allow '/' - volumePathName = volumePathName.BeforeLast(FILE_NAME_SEPARATOR); - - struct stat fileInfo = {}; - while (::lstat(volumePathName.c_str(), &fileInfo) != 0) //go up in folder hierarchy until existing folder is found - { - volumePathName = volumePathName.BeforeLast(FILE_NAME_SEPARATOR); //returns empty string if ch not found - if (volumePathName.empty()) - return 0; //this includes path "/" also! - } - - return fileInfo.st_dev; -} -#endif -} - - -zen::ResponseSame zen::onSameVolume(const Zstring& folderLeft, const Zstring& folderRight) //throw() -{ - const auto serialLeft = retrieveVolumeSerial(folderLeft); //returns 0 on error! - const auto serialRight = retrieveVolumeSerial(folderRight); //returns 0 on error! - if (serialLeft == 0 || serialRight == 0) - return IS_SAME_CANT_SAY; - - return serialLeft == serialRight ? IS_SAME_YES : IS_SAME_NO; -} - - -bool zen::removeFile(const Zstring& filename) //throw FileError; -{ -#ifdef FFS_WIN - //remove file, support for \\?\-prefix - const Zstring filenameFmt = applyLongPathPrefix(filename); - if (!::DeleteFile(filenameFmt.c_str())) -#elif defined FFS_LINUX - if (::unlink(filename.c_str()) != 0) -#endif - { -#ifdef FFS_WIN - //perf: apply ONLY when necessary! - if (::GetLastError() == ERROR_ACCESS_DENIED) //function fails if file is read-only - { - //(try to) normalize file attributes - ::SetFileAttributes(filenameFmt.c_str(), FILE_ATTRIBUTE_NORMAL); - - //now try again... - if (::DeleteFile(filenameFmt.c_str())) - return true; - } - //eval error code before next call - DWORD lastError = ::GetLastError(); -#elif defined FFS_LINUX - int lastError = errno; -#endif - - //no error situation if file is not existing! manual deletion relies on it! - //perf: check is placed in error handling block - //warning: this call changes error code!! - if (!somethingExists(filename)) - return false; //neither file nor any other object (e.g. broken symlink) with that name existing - - throw FileError(_("Error deleting file:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted(lastError)); - } - return true; -} - - -namespace -{ -DEFINE_NEW_FILE_ERROR(ErrorDifferentVolume); - -/* Usage overview: (avoid circular pattern!) - - renameFile() --> renameFile_sub() - | /|\ - \|/ | - Fix8Dot3NameClash() -*/ -//wrapper for file system rename function: -void renameFile_sub(const Zstring& oldName, const Zstring& newName) //throw FileError, ErrorDifferentVolume, ErrorTargetExisting -{ -#ifdef FFS_WIN - const Zstring oldNameFmt = applyLongPathPrefix(oldName); - const Zstring newNameFmt = applyLongPathPrefix(newName); - - if (!::MoveFileEx(oldNameFmt.c_str(), //__in LPCTSTR lpExistingFileName, - newNameFmt.c_str(), //__in_opt LPCTSTR lpNewFileName, - 0)) //__in DWORD dwFlags - { - DWORD lastError = ::GetLastError(); - if (lastError == ERROR_ACCESS_DENIED) //MoveFileEx may fail to rename a read-only file on a SAMBA-share -> (try to) handle this - { - const DWORD oldAttr = ::GetFileAttributes(oldNameFmt.c_str()); - if (oldAttr != INVALID_FILE_ATTRIBUTES && (oldAttr & FILE_ATTRIBUTE_READONLY)) - { - if (::SetFileAttributes(oldNameFmt.c_str(), FILE_ATTRIBUTE_NORMAL)) //remove readonly-attribute - { - //try again... - if (::MoveFileEx(oldNameFmt.c_str(), //__in LPCTSTR lpExistingFileName, - newNameFmt.c_str(), //__in_opt LPCTSTR lpNewFileName, - 0)) //__in DWORD dwFlags - { - //(try to) restore file attributes - ::SetFileAttributes(newNameFmt.c_str(), oldAttr); //don't handle error - return; - } - else - { - lastError = ::GetLastError(); //use error code from second call to ::MoveFileEx() - - //cleanup: (try to) restore file attributes: assume oldName is still existing - ::SetFileAttributes(oldNameFmt.c_str(), oldAttr); - } - } - } - } - - std::wstring errorMessage = _("Error moving file:") + "\n\"" + oldName + "\" ->\n\"" + newName + "\"" + "\n\n" + getLastErrorFormatted(lastError); - - if (lastError == ERROR_NOT_SAME_DEVICE) - throw ErrorDifferentVolume(errorMessage); - else if (lastError == ERROR_FILE_EXISTS) - throw ErrorTargetExisting(errorMessage); - else - throw FileError(errorMessage); - } - -#elif defined FFS_LINUX - if (::rename(oldName.c_str(), newName.c_str()) != 0) - { - const int lastError = errno; - - std::wstring errorMessage = _("Error moving file:") + "\n\"" + oldName + "\" ->\n\"" + newName + "\"" + "\n\n" + getLastErrorFormatted(lastError); - - if (lastError == EXDEV) - throw ErrorDifferentVolume(errorMessage); - else if (lastError == EEXIST) - throw ErrorTargetExisting(errorMessage); - else - throw FileError(errorMessage); - } -#endif -} - - -#ifdef FFS_WIN -/*small wrapper around -::GetShortPathName() -::GetLongPathName() */ -template <typename Function> -Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns empty string on error -{ - const Zstring filenameFmt = applyLongPathPrefix(filename); - - const DWORD bufferSize = fun(filenameFmt.c_str(), NULL, 0); - if (bufferSize == 0) - return Zstring(); - - std::vector<wchar_t> buffer(bufferSize); - - const DWORD rv = fun(filenameFmt.c_str(), //__in LPCTSTR lpszShortPath, - &buffer[0], //__out LPTSTR lpszLongPath, - static_cast<DWORD>(buffer.size())); //__in DWORD cchBuffer - if (rv == 0 || rv >= buffer.size()) - return Zstring(); - - return &buffer[0]; -} - - -Zstring findUnused8Dot3Name(const Zstring& filename) //find a unique 8.3 short name -{ - const Zstring pathPrefix = filename.find(FILE_NAME_SEPARATOR) != Zstring::npos ? - (filename.BeforeLast(FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR) : Zstring(); - - Zstring extension = filename.AfterLast(FILE_NAME_SEPARATOR).AfterLast(Zchar('.')); //extension needn't contain reasonable data - if (extension.empty()) - extension = Zstr("FFS"); - extension.Truncate(3); - - for (int index = 0; index < 100000000; ++index) //filename must be representable by <= 8 characters - { - const Zstring output = pathPrefix + Zstring::fromNumber(index) + Zchar('.') + extension; - if (!somethingExists(output)) //ensure uniqueness - return output; - } - - throw std::runtime_error(std::string("100000000 files, one for each number, exist in this directory? You're kidding...\n") + utf8CvrtTo<std::string>(pathPrefix)); -} - - -bool have8dot3NameClash(const Zstring& filename) -{ - if (filename.find(FILE_NAME_SEPARATOR) == Zstring::npos) - return false; - - if (somethingExists(filename)) //name OR directory! - { - const Zstring origName = filename.AfterLast(FILE_NAME_SEPARATOR); //returns the whole string if ch not found - const Zstring shortName = getFilenameFmt(filename, ::GetShortPathName).AfterLast(FILE_NAME_SEPARATOR); //throw() returns empty string on error - const Zstring longName = getFilenameFmt(filename, ::GetLongPathName) .AfterLast(FILE_NAME_SEPARATOR); // - - if (!shortName.empty() && - !longName.empty() && - EqualFilename()(origName, shortName) && - !EqualFilename()(shortName, longName)) - { - //for filename short and long file name are equal and another unrelated file happens to have the same short name - //e.g. filename == "TESTWE~1", but another file is existing named "TestWeb" with short name ""TESTWE~1" - return true; - } - } - return false; -} - -class Fix8Dot3NameClash -{ -public: - Fix8Dot3NameClash(const Zstring& filename) - { - const Zstring longName = getFilenameFmt(filename, ::GetLongPathName).AfterLast(FILE_NAME_SEPARATOR); //throw() returns empty string on error - - unrelatedFile = filename.BeforeLast(FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + longName; - - //find another name in short format: this ensures the actual short name WILL be renamed as well! - unrelatedFileParked = findUnused8Dot3Name(filename); - - //move already existing short name out of the way for now - renameFile_sub(unrelatedFile, unrelatedFileParked); //throw FileError, ErrorDifferentVolume - //DON'T call renameFile() to avoid reentrance! - } - - ~Fix8Dot3NameClash() - { - //the file system should assign this unrelated file a new (unique) short name - try - { - renameFile_sub(unrelatedFileParked, unrelatedFile); //throw FileError, ErrorDifferentVolume - } - catch (...) {} - } -private: - Zstring unrelatedFile; - Zstring unrelatedFileParked; -}; -#endif -} - - -//rename file: no copying!!! -void zen::renameFile(const Zstring& oldName, const Zstring& newName) //throw FileError, ErrorDifferentVolume, ErrorTargetExisting -{ - try - { - renameFile_sub(oldName, newName); //throw FileError, ErrorDifferentVolume, ErrorTargetExisting - } - catch (const FileError&) - { -#ifdef FFS_WIN - //try to handle issues with already existing short 8.3 file names on Windows - if (have8dot3NameClash(newName)) - { - Fix8Dot3NameClash dummy(newName); //move clashing filename to the side - //now try again... - renameFile_sub(oldName, newName); //throw FileError - return; - } -#endif - throw; - } -} - - -class CopyCallbackImpl : public zen::CallbackCopyFile //callback functionality -{ -public: - CopyCallbackImpl(const Zstring& sourceFile, CallbackMoveFile& callback) : sourceFile_(sourceFile), moveCallback(callback) {} - - virtual void deleteTargetFile(const Zstring& targetFile) { assert(!fileExists(targetFile)); } - - virtual void updateCopyStatus(UInt64 totalBytesTransferred) - { - moveCallback.requestUiRefresh(sourceFile_); - } - -private: - CopyCallbackImpl(const CopyCallbackImpl&); - CopyCallbackImpl& operator=(const CopyCallbackImpl&); - - const Zstring sourceFile_; - CallbackMoveFile& moveCallback; -}; - - -void zen::moveFile(const Zstring& sourceFile, const Zstring& targetFile, bool ignoreExisting, CallbackMoveFile* callback) //throw FileError; -{ - //call back once per file (moveFile() is called by moveDirectory()) - if (callback) - callback->requestUiRefresh(sourceFile); - - const bool targetExisting = fileExists(targetFile); - - if (targetExisting && !ignoreExisting) //test file existence: e.g. Linux might silently overwrite existing symlinks - throw FileError(_("Error moving file:") + "\n\"" + sourceFile + "\" ->\n\"" + targetFile + "\"" + - "\n\n" + _("Target file already existing!")); - - if (!targetExisting) - { - //try to move the file directly without copying - try - { - renameFile(sourceFile, targetFile); //throw FileError, ErrorDifferentVolume - return; //great, we get away cheaply! - } - //if moving failed treat as error (except when it tried to move to a different volume: in this case we will copy the file) - catch (const ErrorDifferentVolume&) {} - - //file is on a different volume: let's copy it - std::unique_ptr<CopyCallbackImpl> copyCallback(callback != NULL ? new CopyCallbackImpl(sourceFile, *callback) : NULL); - - if (symlinkExists(sourceFile)) - copySymlink(sourceFile, targetFile, false); //throw FileError; don't copy filesystem permissions - else - copyFile(sourceFile, targetFile, false, true, copyCallback.get()); //throw FileError; - - //attention: if copy-operation was cancelled an exception is thrown => sourcefile is not deleted, as we wish! - } - - removeFile(sourceFile); //throw FileError - //note: copying file is NOT undone in case of exception: currently this function is called in context of user-defined deletion dir, where this behavior is fine -} - -namespace -{ -class TraverseOneLevel : public zen::TraverseCallback -{ -public: - typedef std::pair<Zstring, Zstring> NamePair; - typedef std::vector<NamePair> NameList; - - TraverseOneLevel(NameList& files, NameList& dirs) : - files_(files), - dirs_(dirs) {} - - virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) - { - files_.push_back(NamePair(shortName, fullName)); - } - - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) - { - if (details.dirLink) - dirs_.push_back(NamePair(shortName, fullName)); - else - files_.push_back(NamePair(shortName, fullName)); - } - - virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) - { - dirs_.push_back(NamePair(shortName, fullName)); - return Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); //DON'T traverse into subdirs; moveDirectory works recursively! - } - - virtual HandleError onError(const std::wstring& errorText) { throw FileError(errorText); } - -private: - TraverseOneLevel(const TraverseOneLevel&); - TraverseOneLevel& operator=(const TraverseOneLevel&); - - NameList& files_; - NameList& dirs_; -}; - - -struct RemoveCallbackImpl : public CallbackRemoveDir -{ - RemoveCallbackImpl(const Zstring& sourceDir, - CallbackMoveFile& moveCallback) : - sourceDir_(sourceDir), - moveCallback_(moveCallback) {} - - virtual void notifyFileDeletion(const Zstring& filename) { moveCallback_.requestUiRefresh(sourceDir_); } - virtual void notifyDirDeletion(const Zstring& dirname) { moveCallback_.requestUiRefresh(sourceDir_); } - -private: - RemoveCallbackImpl(const RemoveCallbackImpl&); - RemoveCallbackImpl& operator=(const RemoveCallbackImpl&); - - const Zstring sourceDir_; - CallbackMoveFile& moveCallback_; -}; -} - - -void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExisting, CallbackMoveFile* callback) //throw FileError; -{ - //call back once per folder - if (callback) - callback->requestUiRefresh(sourceDir); - - const bool targetExisting = dirExists(targetDir); - - if (targetExisting && !ignoreExisting) //directory or symlink exists (or even a file... this error will be caught later) - throw FileError(_("Error moving directory:") + "\n\"" + sourceDir + "\" ->\n\"" + targetDir + "\"" + - "\n\n" + _("Target directory already existing!")); - - const bool isSymlink = symlinkExists(sourceDir); - - if (!targetExisting) - { - //first try to move the directory directly without copying - try - { - renameFile(sourceDir, targetDir); //throw FileError, ErrorDifferentVolume, ErrorTargetExisting - return; //great, we get away cheaply! - } - //if moving failed treat as error (except when it tried to move to a different volume: in this case we will copy the directory) - catch (const ErrorDifferentVolume&) {} - - //create target - if (isSymlink) - copySymlink(sourceDir, targetDir, false); //throw FileError -> don't copy permissions - else - createDirectory(targetDir, sourceDir, false); //throw FileError - } - - if (!isSymlink) //handle symbolic links - { - //move files/folders recursively - TraverseOneLevel::NameList fileList; //list of names: 1. short 2.long - TraverseOneLevel::NameList dirList; // - - //traverse source directory one level - TraverseOneLevel traverseCallback(fileList, dirList); - traverseFolder(sourceDir, false, traverseCallback); //traverse one level, don't follow symlinks - - const Zstring targetDirFormatted = targetDir.EndsWith(FILE_NAME_SEPARATOR) ? //ends with path separator - targetDir : - targetDir + FILE_NAME_SEPARATOR; - - //move files - for (TraverseOneLevel::NameList::const_iterator i = fileList.begin(); i != fileList.end(); ++i) - moveFile(i->second, targetDirFormatted + i->first, ignoreExisting, callback); //throw FileError, ErrorTargetExisting - - //move directories - for (TraverseOneLevel::NameList::const_iterator i = dirList.begin(); i != dirList.end(); ++i) - ::moveDirectoryImpl(i->second, targetDirFormatted + i->first, ignoreExisting, callback); - - //attention: if move-operation was cancelled an exception is thrown => sourceDir is not deleted, as we wish! - } - - //delete source - std::unique_ptr<RemoveCallbackImpl> removeCallback(callback != NULL ? new RemoveCallbackImpl(sourceDir, *callback) : NULL); - removeDirectory(sourceDir, removeCallback.get()); //throw FileError; -} - - -void zen::moveDirectory(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExisting, CallbackMoveFile* callback) //throw FileError; -{ -#ifdef FFS_WIN - const Zstring& sourceDirFormatted = sourceDir; - const Zstring& targetDirFormatted = targetDir; - -#elif defined FFS_LINUX - const Zstring sourceDirFormatted = //remove trailing slash - sourceDir.size() > 1 && sourceDir.EndsWith(FILE_NAME_SEPARATOR) ? //exception: allow '/' - sourceDir.BeforeLast(FILE_NAME_SEPARATOR) : - sourceDir; - const Zstring targetDirFormatted = //remove trailing slash - targetDir.size() > 1 && targetDir.EndsWith(FILE_NAME_SEPARATOR) ? //exception: allow '/' - targetDir.BeforeLast(FILE_NAME_SEPARATOR) : - targetDir; -#endif - - ::moveDirectoryImpl(sourceDirFormatted, targetDirFormatted, ignoreExisting, callback); -} - - -class FilesDirsOnlyTraverser : public zen::TraverseCallback -{ -public: - FilesDirsOnlyTraverser(std::vector<Zstring>& files, std::vector<Zstring>& dirs) : - m_files(files), - m_dirs(dirs) {} - - virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) - { - m_files.push_back(fullName); - } - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) - { - if (details.dirLink) - m_dirs.push_back(fullName); - else - m_files.push_back(fullName); - } - virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) - { - m_dirs.push_back(fullName); - return Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); //DON'T traverse into subdirs; removeDirectory works recursively! - } - virtual HandleError onError(const std::wstring& errorText) { throw FileError(errorText); } - -private: - FilesDirsOnlyTraverser(const FilesDirsOnlyTraverser&); - FilesDirsOnlyTraverser& operator=(const FilesDirsOnlyTraverser&); - - std::vector<Zstring>& m_files; - std::vector<Zstring>& m_dirs; -}; - - -void zen::removeDirectory(const Zstring& directory, CallbackRemoveDir* callback) -{ - //no error situation if directory is not existing! manual deletion relies on it! - if (!somethingExists(directory)) - return; //neither directory nor any other object (e.g. broken symlink) with that name existing - -#ifdef FFS_WIN - const Zstring directoryFmt = applyLongPathPrefix(directory); //support for \\?\-prefix - - //(try to) normalize file attributes: actually NEEDED for symbolic links also! - ::SetFileAttributes(directoryFmt.c_str(), FILE_ATTRIBUTE_NORMAL); -#endif - - //attention: check if directory is a symlink! Do NOT traverse into it deleting contained files!!! - if (symlinkExists(directory)) //remove symlink directly - { -#ifdef FFS_WIN - if (!::RemoveDirectory(directoryFmt.c_str())) -#elif defined FFS_LINUX - if (::unlink(directory.c_str()) != 0) -#endif - throw FileError(_("Error deleting directory:") + "\n\"" + directory + "\"" + "\n\n" + getLastErrorFormatted()); - - if (callback) - callback->notifyDirDeletion(directory); //once per symlink - return; - } - - std::vector<Zstring> fileList; - std::vector<Zstring> dirList; - - //get all files and directories from current directory (WITHOUT subdirectories!) - FilesDirsOnlyTraverser traverser(fileList, dirList); - traverseFolder(directory, false, traverser); //don't follow symlinks - - //delete files - for (std::vector<Zstring>::const_iterator i = fileList.begin(); i != fileList.end(); ++i) - { - const bool workDone = removeFile(*i); - if (callback && workDone) - callback->notifyFileDeletion(*i); //call once per file - } - - //delete directories recursively - for (std::vector<Zstring>::const_iterator i = dirList.begin(); i != dirList.end(); ++i) - removeDirectory(*i, callback); //call recursively to correctly handle symbolic links - - //parent directory is deleted last -#ifdef FFS_WIN - if (!::RemoveDirectory(directoryFmt.c_str())) //remove directory, support for \\?\-prefix -#else - if (::rmdir(directory.c_str()) != 0) -#endif - { - throw FileError(_("Error deleting directory:") + "\n\"" + directory + "\"" + "\n\n" + getLastErrorFormatted()); - } - if (callback) - callback->notifyDirDeletion(directory); //and once per folder -} - - -void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, ProcSymlink procSl) //throw FileError -{ -#ifdef FFS_WIN - FILETIME creationTime = {}; - FILETIME lastWriteTime = tofiletime(modificationTime); - - //####################################### DST hack ########################################### - if (dst::isFatDrive(filename)) //throw() - { - const dst::RawTime encodedTime = dst::fatEncodeUtcTime(lastWriteTime); //throw (std::runtime_error) - creationTime = encodedTime.createTimeRaw; - lastWriteTime = encodedTime.writeTimeRaw; - } - //####################################### DST hack ########################################### - - //privilege SE_BACKUP_NAME doesn't seem to be required here for symbolic links - //note: setting privileges requires admin rights! - - //opening newly created target file may fail due to some AV-software scanning it: no error, we will wait! - //http://support.microsoft.com/?scid=kb%3Ben-us%3B316609&x=17&y=20 - //-> enable as soon it turns out it is required! - - /*const int retryInterval = 50; - const int maxRetries = 2000 / retryInterval; - for (int i = 0; i < maxRetries; ++i) - { - */ - - //may need to remove the readonly-attribute (e.g. FAT usb drives) - FileUpdateHandle targetHandle(filename, [ = ]() - { - return ::CreateFile(applyLongPathPrefix(filename).c_str(), - GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory - (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //process symlinks - NULL); - }); - - if (targetHandle.get() == INVALID_HANDLE_VALUE) - throw FileError(_("Error changing modification time:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - - /* - if (hTarget == INVALID_HANDLE_VALUE && ::GetLastError() == ERROR_SHARING_VIOLATION) - ::Sleep(retryInterval); //wait then retry - else //success or unknown failure - break; - } - */ - - auto isNullTime = [](const FILETIME & ft) { return ft.dwLowDateTime == 0 && ft.dwHighDateTime == 0; }; - - if (!::SetFileTime(targetHandle.get(), - isNullTime(creationTime) ? NULL : &creationTime, - NULL, - &lastWriteTime)) - throw FileError(_("Error changing modification time:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - -#ifndef NDEBUG //dst hack: verify data written - if (dst::isFatDrive(filename) && !dirExists(filename)) //throw() - { - WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {}; - assert(::GetFileAttributesEx(applyLongPathPrefix(filename).c_str(), //__in LPCTSTR lpFileName, - GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId, - &debugeAttr)); //__out LPVOID lpFileInformation - - assert(::CompareFileTime(&debugeAttr.ftCreationTime, &creationTime) == 0); - assert(::CompareFileTime(&debugeAttr.ftLastWriteTime, &lastWriteTime) == 0); - } -#endif - -#elif defined FFS_LINUX - if (procSl == SYMLINK_FOLLOW) - { - struct utimbuf newTimes = {}; - newTimes.actime = ::time(NULL); - newTimes.modtime = to<time_t>(modificationTime); - - // set new "last write time" - if (::utime(filename.c_str(), &newTimes) != 0) - throw FileError(_("Error changing modification time:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - } - else - { - struct timeval newTimes[2] = {}; - newTimes[0].tv_sec = ::time(NULL); /* seconds */ - newTimes[0].tv_usec = 0; /* microseconds */ - - newTimes[1].tv_sec = to<time_t>(modificationTime); - newTimes[1].tv_usec = 0; - - if (::lutimes(filename.c_str(), newTimes) != 0) - throw FileError(_("Error changing modification time:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted()); - } -#endif -} - - -namespace -{ -#ifdef FFS_WIN -Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory; throw (FileError) -{ - //open handle to target of symbolic link - const HANDLE hDir = ::CreateFile(applyLongPathPrefix(dirLinkName).c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, //needed to open a directory - NULL); - if (hDir == INVALID_HANDLE_VALUE) - throw FileError(_("Error resolving symbolic link:") + "\n\"" + dirLinkName + "\"" + "\n\n" + getLastErrorFormatted()); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hDir)); - - const DWORD BUFFER_SIZE = 10000; - std::vector<wchar_t> targetPath(BUFFER_SIZE); - - //dynamically load windows API function - typedef DWORD (WINAPI *GetFinalPathNameByHandleWFunc)(HANDLE hFile, - LPTSTR lpszFilePath, - DWORD cchFilePath, - DWORD dwFlags); - const util::DllFun<GetFinalPathNameByHandleWFunc> getFinalPathNameByHandle(L"kernel32.dll", "GetFinalPathNameByHandleW"); - if (!getFinalPathNameByHandle) - throw FileError(_("Error loading library function:") + "\n\"" + "GetFinalPathNameByHandleW" + "\""); - - const DWORD charsWritten = getFinalPathNameByHandle(hDir, //__in HANDLE hFile, - &targetPath[0], //__out LPTSTR lpszFilePath, - BUFFER_SIZE, //__in DWORD cchFilePath, - FILE_NAME_NORMALIZED); //__in DWORD dwFlags - if (charsWritten >= BUFFER_SIZE || charsWritten == 0) - { - std::wstring errorMessage = _("Error resolving symbolic link:") + "\n\"" + dirLinkName + "\""; - if (charsWritten == 0) - errorMessage += L"\n\n" + getLastErrorFormatted(); - throw FileError(errorMessage); - } - - return Zstring(&targetPath[0], charsWritten); -} -#endif - - -#ifdef HAVE_SELINUX -//copy SELinux security context -void copySecurityContext(const Zstring& source, const Zstring& target, ProcSymlink procSl) //throw FileError -{ - security_context_t contextSource = NULL; - const int rv = procSl == SYMLINK_FOLLOW ? - ::getfilecon(source.c_str(), &contextSource) : - ::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 - return; - - throw FileError(_("Error reading security context:") + "\n\"" + source + "\"" + "\n\n" + getLastErrorFormatted()); - } - LOKI_ON_BLOCK_EXIT2(::freecon(contextSource)); - - { - security_context_t contextTarget = NULL; - const int rv2 = procSl == SYMLINK_FOLLOW ? - ::getfilecon(target.c_str(), &contextTarget) : - ::lgetfilecon(target.c_str(), &contextTarget); - if (rv2 < 0) - { - if (errno == EOPNOTSUPP) - return; - //else: still try to set security context - } - else - { - LOKI_ON_BLOCK_EXIT2(::freecon(contextTarget)); - - if (::strcmp(contextSource, contextTarget) == 0) //nothing to do - return; - } - } - - const int rv3 = procSl == SYMLINK_FOLLOW ? - ::setfilecon(target.c_str(), contextSource) : - ::lsetfilecon(target.c_str(), contextSource); - if (rv3 < 0) - throw FileError(_("Error writing security context:") + "\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted()); -} -#endif //HAVE_SELINUX - - -//copy permissions for files, directories or symbolic links: requires admin rights -void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSymlink procSl) //throw FileError; -{ -#ifdef FFS_WIN - //setting privileges requires admin rights! - try - { - //enable privilege: required to read/write SACL information - Privileges::getInstance().ensureActive(SE_SECURITY_NAME); //polling allowed... - - //enable privilege: required to copy owner information - Privileges::getInstance().ensureActive(SE_RESTORE_NAME); - - //the following privilege may be required according to http://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx (although not needed nor active in my tests) - Privileges::getInstance().ensureActive(SE_BACKUP_NAME); - } - catch (const FileError& e) - { - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + e.msg()); - } - - PSECURITY_DESCRIPTOR buffer = NULL; - PSID owner = NULL; - PSID group = NULL; - PACL dacl = NULL; - PACL sacl = NULL; - - //http://msdn.microsoft.com/en-us/library/aa364399(v=VS.85).aspx - const HANDLE hSource = ::CreateFile(applyLongPathPrefix(source).c_str(), - READ_CONTROL | ACCESS_SYSTEM_SECURITY, //ACCESS_SYSTEM_SECURITY required for SACL access - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory - NULL); - if (hSource == INVALID_HANDLE_VALUE) - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted() + " (OR)"); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hSource)); - - // 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, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInfo, - &owner, //__out_opt PSID *ppsidOwner, - &group, //__out_opt PSID *ppsidGroup, - &dacl, //__out_opt PACL *ppDacl, - &sacl, //__out_opt PACL *ppSacl, - &buffer); //__out_opt PSECURITY_DESCRIPTOR *ppSecurityDescriptor - if (rc != ERROR_SUCCESS) - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted(rc) + " (R)"); - LOKI_ON_BLOCK_EXIT2(::LocalFree(buffer)); - - //may need to remove the readonly-attribute (e.g. FAT usb drives) - FileUpdateHandle targetHandle(target, [ = ]() - { - return ::CreateFile(applyLongPathPrefix(target).c_str(), // lpFileName - GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY, // dwDesiredAccess: all four seem to be required!!! - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // dwShareMode - 0, // lpSecurityAttributes - OPEN_EXISTING, // dwCreationDisposition - FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), // dwFlagsAndAttributes - NULL); // hTemplateFile - }); - - if (targetHandle.get() == INVALID_HANDLE_VALUE) - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted() + " (OW)"); - - // rc = ::SetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(target).c_str()), //__in LPTSTR pObjectName, -> does NOT dereference symlinks! - rc = ::SetSecurityInfo(targetHandle.get(), //__in LPTSTR pObjectName, - SE_FILE_OBJECT, //__in SE_OBJECT_TYPE ObjectType, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInfo, - owner, //__in_opt PSID psidOwner, - group, //__in_opt PSID psidGroup, - dacl, //__in_opt PACL pDacl, - sacl); //__in_opt PACL pSacl - - if (rc != ERROR_SUCCESS) - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted(rc) + " (W)"); - -#elif defined FFS_LINUX - -#ifdef HAVE_SELINUX //copy SELinux security context - copySecurityContext(source, target, procSl); //throw FileError -#endif - - struct stat fileInfo = {}; - if (procSl == SYMLINK_FOLLOW) - { - 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) - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted() + " (R)"); - } - else - { - 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() - throw FileError(_("Error copying file permissions:") + "\n\"" + source + "\" ->\n\"" + target + "\"" + "\n\n" + getLastErrorFormatted() + " (W)"); - } -#endif -} - - -void createDirectory_straight(const Zstring& directory, const Zstring& templateDir, bool copyFilePermissions, int level) -{ - //default directory creation -#ifdef FFS_WIN - //don't use ::CreateDirectoryEx: - //- it may fail with "wrong parameter (error code 87)" when source is on mapped online storage - //- automatically copies symbolic links if encountered: unfortunately it doesn't copy symlinks over network shares but silently creates empty folders instead (on XP)! - //- it isn't able to copy most junctions because of missing permissions (although target path can be retrieved alternatively!) - if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), NULL)) -#elif defined FFS_LINUX - if (::mkdir(directory.c_str(), 0755) != 0) -#endif - { - if (level != 0) return; - throw FileError(_("Error creating directory:") + "\n\"" + directory + "\"" + "\n\n" + getLastErrorFormatted()); - } - - if (!templateDir.empty()) - { -#ifdef FFS_WIN - //try to copy file attributes - Zstring sourcePath; - - if (symlinkExists(templateDir)) //dereference symlink! - { - try - { - //get target directory of symbolic link - sourcePath = resolveDirectorySymlink(templateDir); //throw FileError - } - catch (FileError&) {} //dereferencing a symbolic link usually fails if it is located on network drive or client is XP: NOT really an error... - } - else //no symbolic link - sourcePath = templateDir; - - //try to copy file attributes - if (!sourcePath.empty()) - { - const DWORD sourceAttr = ::GetFileAttributes(applyLongPathPrefix(sourcePath).c_str()); - if (sourceAttr != INVALID_FILE_ATTRIBUTES) - { - const bool isCompressed = (sourceAttr & FILE_ATTRIBUTE_COMPRESSED) != 0; - const bool isEncrypted = (sourceAttr & FILE_ATTRIBUTE_ENCRYPTED) != 0; - - ::SetFileAttributes(applyLongPathPrefix(directory).c_str(), sourceAttr); - - if (isEncrypted) - ::EncryptFile(directory.c_str()); //seems no long path is required (check passed!) - - if (isCompressed) - { - HANDLE hDir = ::CreateFile(applyLongPathPrefix(directory).c_str(), - GENERIC_READ | GENERIC_WRITE, //read access required for FSCTL_SET_COMPRESSION - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hDir != INVALID_HANDLE_VALUE) - { - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hDir)); - - USHORT cmpState = COMPRESSION_FORMAT_DEFAULT; - - DWORD bytesReturned = 0; - ::DeviceIoControl(hDir, //handle to file or directory - FSCTL_SET_COMPRESSION, //dwIoControlCode - &cmpState, //input buffer - sizeof(cmpState), //size of input buffer - NULL, //lpOutBuffer - 0, //OutBufferSize - &bytesReturned, //number of bytes returned - NULL); //OVERLAPPED structure - } - } - } - } -#endif - Loki::ScopeGuard guardNewDir = Loki::MakeGuard([&]() { removeDirectory(directory); }); //ensure cleanup: - - //enforce copying file permissions: it's advertized on GUI... - if (copyFilePermissions) - copyObjectPermissions(templateDir, directory, SYMLINK_FOLLOW); //throw FileError - - guardNewDir.Dismiss(); //target has been created successfully! - } -} - - -void createDirectoryRecursively(const Zstring& directory, const Zstring& templateDir, bool copyFilePermissions, int level) -{ - if (level == 100) //catch endless recursion - return; - -#ifdef FFS_WIN - std::unique_ptr<Fix8Dot3NameClash> fnc; - if (somethingExists(directory)) - { - //handle issues with already existing short 8.3 file names on Windows - if (have8dot3NameClash(directory)) - fnc.reset(new Fix8Dot3NameClash(directory)); //move clashing object to the side - else if (dirExists(directory)) - return; - } -#elif defined FFS_LINUX - if (dirExists(directory)) - return; -#endif - else //if "somethingExists" we needn't create the parent directory - { - //try to create parent folders first - const Zstring dirParent = directory.BeforeLast(FILE_NAME_SEPARATOR); - if (!dirParent.empty() && !dirExists(dirParent)) - { - //call function recursively - const Zstring templateParent = templateDir.BeforeLast(FILE_NAME_SEPARATOR); //returns empty string if ch not found - createDirectoryRecursively(dirParent, templateParent, copyFilePermissions, level + 1); - } - } - - //now creation should be possible - createDirectory_straight(directory, templateDir, copyFilePermissions, level); //throw FileError -} -} - - -void zen::createDirectory(const Zstring& directory, const Zstring& templateDir, bool copyFilePermissions) -{ - //remove trailing separator - const Zstring dirFormatted = directory.EndsWith(FILE_NAME_SEPARATOR) ? - directory.BeforeLast(FILE_NAME_SEPARATOR) : - directory; - - const Zstring templateFormatted = templateDir.EndsWith(FILE_NAME_SEPARATOR) ? - templateDir.BeforeLast(FILE_NAME_SEPARATOR) : - templateDir; - - createDirectoryRecursively(dirFormatted, templateFormatted, copyFilePermissions, 0); -} - - -void zen::createDirectory(const Zstring& directory) -{ - zen::createDirectory(directory, Zstring(), false); -} - - -void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool copyFilePermissions) //throw FileError -{ - const Zstring linkPath = getSymlinkRawTargetString(sourceLink); //accept broken symlinks; throw FileError - -#ifdef FFS_WIN - const bool isDirLink = [&]() -> bool - { - const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(sourceLink).c_str()); - return ret != INVALID_FILE_ATTRIBUTES && (ret& FILE_ATTRIBUTE_DIRECTORY); - }(); - - //dynamically load windows API function - typedef BOOLEAN (WINAPI *CreateSymbolicLinkFunc)(LPCTSTR lpSymlinkFileName, LPCTSTR lpTargetFileName, DWORD dwFlags); - - const util::DllFun<CreateSymbolicLinkFunc> createSymbolicLink(L"kernel32.dll", "CreateSymbolicLinkW"); - if (!createSymbolicLink) - throw FileError(_("Error loading library function:") + "\n\"" + "CreateSymbolicLinkW" + "\""); - - if (!createSymbolicLink(targetLink.c_str(), //__in LPTSTR lpSymlinkFileName, - seems no long path prefix is required... - linkPath.c_str(), //__in LPTSTR lpTargetFileName, - (isDirLink ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))) //__in DWORD dwFlags -#elif defined FFS_LINUX - if (::symlink(linkPath.c_str(), targetLink.c_str()) != 0) -#endif - throw FileError(_("Error copying symbolic link:") + "\n\"" + sourceLink + "\" ->\n\"" + targetLink + "\"" + "\n\n" + getLastErrorFormatted()); - - //allow only consistent objects to be created -> don't place before ::symlink, targetLink may already exist - Loki::ScopeGuard guardNewDir = Loki::MakeGuard([&]() - { -#ifdef FFS_WIN - if (isDirLink) - removeDirectory(targetLink); - else -#endif - removeFile(targetLink); - }); - - //file times: essential for a symlink: enforce this! (don't just try!) - { - const Int64 modTime = getFileTime(sourceLink, SYMLINK_DIRECT); //throw FileError - setFileTime(targetLink, modTime, SYMLINK_DIRECT); //throw FileError - } - - if (copyFilePermissions) - copyObjectPermissions(sourceLink, targetLink, SYMLINK_DIRECT); //throw FileError - - guardNewDir.Dismiss(); //target has been created successfully! -} - - -namespace -{ -Zstring createTempName(const Zstring& filename) -{ - Zstring output = filename + zen::TEMP_FILE_ENDING; - - //ensure uniqueness - for (int i = 1; somethingExists(output); ++i) - output = filename + Zchar('_') + Zstring::fromNumber(i) + zen::TEMP_FILE_ENDING; - - return output; -} - -#ifdef FFS_WIN -class CallbackData -{ -public: - CallbackData(CallbackCopyFile* cb, //may be NULL - const Zstring& sourceFile, - const Zstring& targetFile, - bool osIsvistaOrLater) : - userCallback(cb), - sourceFile_(sourceFile), - targetFile_(targetFile), - osIsvistaOrLater_(osIsvistaOrLater), - exceptionInUserCallback(false) {} - - CallbackCopyFile* userCallback; //optional! - const Zstring& sourceFile_; - const Zstring& targetFile_; - const bool osIsvistaOrLater_; - - //there is some mixed responsibility in this class, pure read-only data and abstraction for error reporting - //however we need to keep it at one place as ::CopyFileEx() requires! - - void reportUserException(const UInt64& bytesTransferred) - { - exceptionInUserCallback = true; - bytesTransferredOnException = bytesTransferred; - } - - void reportError(const std::wstring& message) { errorMsg = message; } - - void evaluateErrors() //throw - { - if (exceptionInUserCallback) - { - assert(userCallback); - if (userCallback) - userCallback->updateCopyStatus(bytesTransferredOnException); //rethrow (hopefully!) - } - if (!errorMsg.empty()) - throw FileError(errorMsg); - } - - void setSrcAttr(const FileAttrib& attr) { sourceAttr = attr; } - FileAttrib getSrcAttr() const { assert(sourceAttr.modificationTime != 0); return sourceAttr; } - -private: - CallbackData(const CallbackData&); - CallbackData& operator=(const CallbackData&); - - FileAttrib sourceAttr; - std::wstring errorMsg; // - bool exceptionInUserCallback; //these two are exclusive! - UInt64 bytesTransferredOnException; -}; - - -DWORD CALLBACK copyCallbackInternal( - LARGE_INTEGER totalFileSize, - LARGE_INTEGER totalBytesTransferred, - LARGE_INTEGER streamSize, - LARGE_INTEGER streamBytesTransferred, - DWORD dwStreamNumber, - DWORD dwCallbackReason, - HANDLE hSourceFile, - HANDLE hDestinationFile, - LPVOID lpData) -{ - //this callback is invoked for block sizes managed by Windows, these may vary from e.g. 64 kB up to 1MB. It seems this is dependent from file size amongst others. - - //symlink handling: - //if source is a symlink and COPY_FILE_COPY_SYMLINK is specified, this callback is NOT invoked! - //if source is a symlink and COPY_FILE_COPY_SYMLINK is NOT specified, this callback is called and hSourceFile is a handle to the *target* of the link! - - //file time handling: - //::CopyFileEx() will copy file modification time (only) over from source file AFTER the last inocation of this callback - //=> it is possible to adapt file creation time of target in here, but NOT file modification time! - - CallbackData& cbd = *static_cast<CallbackData*>(lpData); - - //#################### return source file attributes ################################ - if (dwCallbackReason == CALLBACK_STREAM_SWITCH) //called up front for every file (even if 0-sized) - { - BY_HANDLE_FILE_INFORMATION fileInfo = {}; - if (!::GetFileInformationByHandle(hSourceFile, &fileInfo)) - { - cbd.reportError(_("Error reading file attributes:") + "\n\"" + cbd.sourceFile_ + "\"" + "\n\n" + getLastErrorFormatted()); - return PROGRESS_CANCEL; - } - - const FileAttrib attr = { UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh), - toTimeT(fileInfo.ftLastWriteTime) - }; - //extractFileID(fileInfo)); - - cbd.setSrcAttr(attr); - - //#################### copy file creation time ################################ - FILETIME creationTime = {}; - - if (!::GetFileTime(hSourceFile, //__in HANDLE hFile, - &creationTime, //__out_opt LPFILETIME lpCreationTime, - NULL, //__out_opt LPFILETIME lpLastAccessTime, - NULL)) //__out_opt LPFILETIME lpLastWriteTime - { - cbd.reportError(_("Error reading file attributes:") + "\n\"" + cbd.sourceFile_ + "\"" + "\n\n" + getLastErrorFormatted()); - return PROGRESS_CANCEL; - } - - if (!::SetFileTime(hDestinationFile, - &creationTime, - NULL, - NULL)) - { - cbd.reportError(_("Error changing modification time:") + "\n\"" + cbd.targetFile_ + "\"" + "\n\n" + getLastErrorFormatted()); - return PROGRESS_CANCEL; - } - //############################################################################## - } - - //if (totalFileSize.QuadPart == totalBytesTransferred.QuadPart) {} //called after copy operation is finished - note: for 0-sized files this callback is invoked just ONCE! - - if (cbd.userCallback) - { - //some odd check for some possible(?) error condition - if (totalBytesTransferred.QuadPart < 0) //let's see if someone answers the call... - ::MessageBox(NULL, L"You've just discovered a bug in WIN32 API function \"CopyFileEx\"! \n\n\ - Please write a mail to the author of FreeFileSync at zhnmju123@gmx.de and simply state that\n\ - \"totalBytesTransferred.HighPart can be below zero\"!\n\n\ - This will then be handled in future versions of FreeFileSync.\n\nThanks -ZenJu", - NULL, 0); - try - { - cbd.userCallback->updateCopyStatus(UInt64(totalBytesTransferred.QuadPart)); - } - catch (...) - { -//#warning migrate to std::exception_ptr when available - - cbd.reportUserException(UInt64(totalBytesTransferred.QuadPart)); - return PROGRESS_CANCEL; - } - } - return PROGRESS_CONTINUE; -} - - -#ifndef COPY_FILE_ALLOW_DECRYPTED_DESTINATION -#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x00000008 -#endif - -bool supportForNonEncryptedDestination() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - //encrypted destination is not supported with Windows 2000 - if (::GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5 || - (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 0); //2000 has majorVersion == 5, minorVersion == 0 - //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} - - -void rawCopyWinApi_sub(const Zstring& sourceFile, - const Zstring& targetFile, - CallbackCopyFile* callback, - FileAttrib* sourceAttr) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked -{ - Loki::ScopeGuard guardTarget = Loki::MakeGuard(&removeFile, targetFile); //transactional behavior: guard just before starting copy, we don't trust ::CopyFileEx(), do we ;) - - DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS; - - //allow copying from encrypted to non-encrytped location - static bool nonEncSupported = false; - { - static boost::once_flag initNonEncOnce = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(initNonEncOnce, []() { nonEncSupported = supportForNonEncryptedDestination(); }); - } - if (nonEncSupported) - copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION; - - static bool osIsvistaOrLater = false; - { - static boost::once_flag initVistaLaterOnce = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(initVistaLaterOnce, []() { osIsvistaOrLater = dst::vistaOrLater(); }); - } - - CallbackData cbd(callback, sourceFile, targetFile, osIsvistaOrLater); - - const bool success = ::CopyFileEx( //same performance like CopyFile() - applyLongPathPrefix(sourceFile).c_str(), - applyLongPathPrefix(targetFile).c_str(), - copyCallbackInternal, - &cbd, - NULL, - copyFlags) == TRUE; //silence x64 perf warning - - cbd.evaluateErrors(); //throw ?, process errors in callback first! - if (!success) - { - const DWORD lastError = ::GetLastError(); - - //don't suppress "lastError == ERROR_REQUEST_ABORTED": a user aborted operation IS an error condition! - - //assemble error message... - std::wstring errorMessage = _("Error copying file:") + "\n\"" + sourceFile + "\" ->\n\"" + targetFile + "\"" + - "\n\n" + getLastErrorFormatted(lastError); - - //if file is locked (try to) use Windows Volume Shadow Copy Service - if (lastError == ERROR_SHARING_VIOLATION || - lastError == ERROR_LOCK_VIOLATION) - throw ErrorFileLocked(errorMessage); - - if (lastError == ERROR_FILE_EXISTS) //if target is existing this functions is expected to throw ErrorTargetExisting!!! - { - guardTarget.Dismiss(); //don't delete file that existed previously! - throw ErrorTargetExisting(errorMessage); - } - - if (lastError == ERROR_PATH_NOT_FOUND) - { - guardTarget.Dismiss(); //not relevant - throw ErrorTargetPathMissing(errorMessage); - } - - 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) >= 4U * UInt64(1024U * 1024 * 1024)) //throw FileError - errorMessage += L"\nFAT volume cannot store files larger than 4 gigabyte!"; - - //note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filename is of a restricted type. - } - catch (...) {} - - throw FileError(errorMessage); - } - - if (sourceAttr) - *sourceAttr = cbd.getSrcAttr(); - - { - const Int64 modTime = getFileTime(sourceFile, SYMLINK_FOLLOW); //throw FileError - setFileTime(targetFile, modTime, SYMLINK_FOLLOW); //throw FileError - //note: this sequence leads to a loss of precision of up to 1 sec! - //perf-loss on USB sticks with many small files of about 30%! damn! - } - - guardTarget.Dismiss(); //target has been created successfully! -} - - -inline -void rawCopyWinApi(const Zstring& sourceFile, - const Zstring& targetFile, - CallbackCopyFile* callback, - FileAttrib* sourceAttr) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked -{ - try - { - rawCopyWinApi_sub(sourceFile, targetFile, callback, sourceAttr); // throw ... - } - catch (ErrorTargetExisting&) - { - //try to handle issues with already existing short 8.3 file names on Windows - if (have8dot3NameClash(targetFile)) - { - Fix8Dot3NameClash dummy(targetFile); //move clashing filename to the side - rawCopyWinApi_sub(sourceFile, targetFile, callback, sourceAttr); //throw FileError; the short filename name clash is solved, this should work now - return; - } - throw; - } -} - -//void rawCopyWinOptimized(const Zstring& sourceFile, -// const Zstring& targetFile, -// CallbackCopyFile* callback) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked -//{ -// /* -// BackupRead() FileRead() CopyFileEx() -// -------------------------------------------- -// Attributes NO NO YES -// create time NO NO NO -// ADS YES NO YES -// Encrypted NO(silent fail) NO YES -// Compressed NO NO NO -// Sparse YES NO NO -// PERF 6% faster - -// -// Mark stream as compressed: FSCTL_SET_COMPRESSION -// compatible with: BackupRead() FileRead() -// */ -// -// //open sourceFile for reading -// HANDLE hFileIn = ::CreateFile(applyLongPathPrefix(sourceFile).c_str(), -// GENERIC_READ, -// FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //all shared modes are required to read files that are open in other applications -// 0, -// OPEN_EXISTING, -// FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); -// if (hFileIn == INVALID_HANDLE_VALUE) -// { -// const DWORD lastError = ::GetLastError(); -// const std::wstring& errorMessage = _("Error opening file:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted(lastError); -// -// //if file is locked (try to) use Windows Volume Shadow Copy Service -// if (lastError == ERROR_SHARING_VIOLATION || -// lastError == ERROR_LOCK_VIOLATION) -// throw ErrorFileLocked(errorMessage); -// -// throw FileError(errorMessage); -// } -// LOKI_ON_BLOCK_EXIT2(::CloseHandle, hFileIn); -// -// -// BY_HANDLE_FILE_INFORMATION infoFileIn = {}; -// if (!::GetFileInformationByHandle(hFileIn, &infoFileIn)) -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); -// -// //####################################### DST hack ########################################### -// if (dst::isFatDrive(sourceFile)) //throw() -// { -// const dst::RawTime rawTime(infoFileIn.ftCreationTime, infoFileIn.ftLastWriteTime); -// if (dst::fatHasUtcEncoded(rawTime)) //throw (std::runtime_error) -// { -// infoFileIn.ftLastWriteTime = dst::fatDecodeUtcTime(rawTime); //return last write time in real UTC, throw (std::runtime_error) -// ::GetSystemTimeAsFileTime(&infoFileIn.ftCreationTime); //real creation time information is not available... -// } -// } -// -// if (dst::isFatDrive(targetFile)) //throw() -// { -// const dst::RawTime encodedTime = dst::fatEncodeUtcTime(infoFileIn.ftLastWriteTime); //throw (std::runtime_error) -// infoFileIn.ftCreationTime = encodedTime.createTimeRaw; -// infoFileIn.ftLastWriteTime = encodedTime.writeTimeRaw; -// } -// //####################################### DST hack ########################################### -// -// const DWORD validAttribs = FILE_ATTRIBUTE_READONLY | -// FILE_ATTRIBUTE_HIDDEN | -// FILE_ATTRIBUTE_SYSTEM | -// FILE_ATTRIBUTE_ARCHIVE | //those two are not set properly (not worse than ::CopyFileEx()) -// FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | // -// FILE_ATTRIBUTE_ENCRYPTED; -// -// //create targetFile and open it for writing -// HANDLE hFileOut = ::CreateFile(applyLongPathPrefix(targetFile).c_str(), -// GENERIC_READ | GENERIC_WRITE, //read access required for FSCTL_SET_COMPRESSION -// FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, -// 0, -// CREATE_NEW, -// (infoFileIn.dwFileAttributes & validAttribs) | FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); -// if (hFileOut == INVALID_HANDLE_VALUE) -// { -// const DWORD lastError = ::GetLastError(); -// const std::wstring& errorMessage = _("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted(lastError); -// -// if (lastError == ERROR_FILE_EXISTS) -// throw ErrorTargetExisting(errorMessage); -// -// if (lastError == ERROR_PATH_NOT_FOUND) -// throw ErrorTargetPathMissing(errorMessage); -// -// throw FileError(errorMessage); -// } -// Loki::ScopeGuard guardTarget = Loki::MakeGuard(&removeFile, targetFile); //transactional behavior: guard just after opening target and before managing hFileOut -// -// LOKI_ON_BLOCK_EXIT2(::CloseHandle, hFileOut); -// -// -//#ifndef _MSC_VER -//#warning teste perf von GetVolumeInformationByHandleW -//#endif -// DWORD fsFlags = 0; -// if (!GetVolumeInformationByHandleW(hFileOut, //__in HANDLE hFile, -// NULL, //__out_opt LPTSTR lpVolumeNameBuffer, -// 0, //__in DWORD nVolumeNameSize, -// NULL, //__out_opt LPDWORD lpVolumeSerialNumber, -// NULL, //__out_opt LPDWORD lpMaximumComponentLength, -// &fsFlags, //__out_opt LPDWORD lpFileSystemFlags, -// NULL, //__out LPTSTR lpFileSystemNameBuffer, -// 0)) //__in DWORD nFileSystemNameSize -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); -// -// const bool sourceIsEncrypted = (infoFileIn.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; -// const bool sourceIsCompressed = (infoFileIn.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0; -// const bool sourceIsSparse = (infoFileIn.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0; -// -// bool targetSupportSparse = (fsFlags & FILE_SUPPORTS_SPARSE_FILES) != 0; -// bool targetSupportCompressed = (fsFlags & FILE_FILE_COMPRESSION ) != 0; -// bool targetSupportStreams = (fsFlags & FILE_NAMED_STREAMS ) != 0; -// -// -// const bool useBackupFun = !sourceIsEncrypted; //http://msdn.microsoft.com/en-us/library/aa362509(v=VS.85).aspx -// -// if (sourceIsCompressed && targetSupportCompressed) -// { -// USHORT cmpState = COMPRESSION_FORMAT_DEFAULT; -// -// DWORD bytesReturned = 0; -// if (!DeviceIoControl(hFileOut, //handle to file or directory -// FSCTL_SET_COMPRESSION, //dwIoControlCode -// &cmpState, //input buffer -// sizeof(cmpState), //size of input buffer -// NULL, //lpOutBuffer -// 0, //OutBufferSize -// &bytesReturned, //number of bytes returned -// NULL)) //OVERLAPPED structure -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + -// "\nFailed to write NTFS compressed attribute!"); -// } -// -// //although it seems the sparse attribute is set automatically by BackupWrite, we are required to do this manually: http://support.microsoft.com/kb/271398/en-us -// if (sourceIsSparse && targetSupportSparse) -// { -// if (useBackupFun) -// { -// DWORD bytesReturned = 0; -// if (!DeviceIoControl(hFileOut, //handle to file -// FSCTL_SET_SPARSE, //dwIoControlCode -// NULL, //input buffer -// 0, //size of input buffer -// NULL, //lpOutBuffer -// 0, //OutBufferSize -// &bytesReturned, //number of bytes returned -// NULL)) //OVERLAPPED structure -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + -// "\nFailed to write NTFS sparse attribute!"); -// } -// } -// -// -// const DWORD BUFFER_SIZE = 512 * 1024; //512 kb seems to be a reasonable buffer size -// static boost::thread_specific_ptr<std::vector<char>> cpyBuf; -// if (!cpyBuf.get()) -// cpyBuf.reset(new std::vector<char>(BUFFER_SIZE)); //512 kb seems to be a reasonable buffer size -// std::vector<char>& buffer = *cpyBuf; -// -// struct ManageCtxt //manage context for BackupRead()/BackupWrite() -// { -// ManageCtxt() : read(NULL), write(NULL) {} -// ~ManageCtxt() -// { -// if (read != NULL) -// ::BackupRead (0, NULL, 0, NULL, true, false, &read); -// if (write != NULL) -// ::BackupWrite(0, NULL, 0, NULL, true, false, &write); -// } -// -// LPVOID read; -// LPVOID write; -// } context; -// -// //copy contents of sourceFile to targetFile -// UInt64 totalBytesTransferred; -// -// bool eof = false; -// do -// { -// DWORD bytesRead = 0; -// -// if (useBackupFun) -// { -// if (!::BackupRead(hFileIn, //__in HANDLE hFile, -// &buffer[0], //__out LPBYTE lpBuffer, -// BUFFER_SIZE, //__in DWORD nNumberOfBytesToRead, -// &bytesRead, //__out LPDWORD lpNumberOfBytesRead, -// false, //__in BOOL bAbort, -// false, //__in BOOL bProcessSecurity, -// &context.read)) //__out LPVOID *lpContext -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + -// "\n\n" + getLastErrorFormatted()); -// } -// else if (!::ReadFile(hFileIn, //__in HANDLE hFile, -// &buffer[0], //__out LPVOID lpBuffer, -// BUFFER_SIZE, //__in DWORD nNumberOfBytesToRead, -// &bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead, -// NULL)) //__inout_opt LPOVERLAPPED lpOverlapped -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + -// "\n\n" + getLastErrorFormatted()); -// -// if (bytesRead > BUFFER_SIZE) -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + -// "\n\n" + "buffer overflow"); -// -// if (bytesRead < BUFFER_SIZE) -// eof = true; -// -// DWORD bytesWritten = 0; -// -// if (useBackupFun) -// { -// if (!::BackupWrite(hFileOut, //__in HANDLE hFile, -// &buffer[0], //__in LPBYTE lpBuffer, -// bytesRead, //__in DWORD nNumberOfBytesToWrite, -// &bytesWritten, //__out LPDWORD lpNumberOfBytesWritten, -// false, //__in BOOL bAbort, -// false, //__in BOOL bProcessSecurity, -// &context.write)) //__out LPVOID *lpContext -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + " (w)"); //w -> distinguish from fopen error message! -// } -// else if (!::WriteFile(hFileOut, //__in HANDLE hFile, -// &buffer[0], //__out LPVOID lpBuffer, -// bytesRead, //__in DWORD nNumberOfBytesToWrite, -// &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten, -// NULL)) //__inout_opt LPOVERLAPPED lpOverlapped -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + " (w)"); //w -> distinguish from fopen error message! -// -// if (bytesWritten != bytesRead) -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + "\n\n" + "incomplete write"); -// -// totalBytesTransferred += bytesRead; -// -//#ifndef _MSC_VER -//#warning totalBytesTransferred kann größer als filesize sein!! -//#endif -// -// //invoke callback method to update progress indicators -// if (callback != NULL) -// switch (callback->updateCopyStatus(totalBytesTransferred)) -// { -// case CallbackCopyFile::CONTINUE: -// break; -// -// case CallbackCopyFile::CANCEL: //a user aborted operation IS an error condition! -// throw FileError(_("Error copying file:") + "\n\"" + sourceFile + "\" ->\n\"" + -// targetFile + "\"\n\n" + _("Operation aborted!")); -// } -// } -// while (!eof); -// -// -// if (totalBytesTransferred == 0) //BackupRead silently fails reading encrypted files -> double check! -// { -// LARGE_INTEGER inputSize = {}; -// if (!::GetFileSizeEx(hFileIn, &inputSize)) -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); -// -// if (inputSize.QuadPart != 0) -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + "\n\n" + "unknown error"); -// } -// -// //time needs to be set at the end: BackupWrite() changes file time -// if (!::SetFileTime(hFileOut, -// &infoFileIn.ftCreationTime, -// NULL, -// &infoFileIn.ftLastWriteTime)) -// throw FileError(_("Error changing modification time:") + "\n\"" + targetFile + "\"" + "\n\n" + getLastErrorFormatted()); -// -// -//#ifndef NDEBUG //dst hack: verify data written -// if (dst::isFatDrive(targetFile)) //throw() -// { -// WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {}; -// assert(::GetFileAttributesEx(applyLongPathPrefix(targetFile).c_str(), //__in LPCTSTR lpFileName, -// GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId, -// &debugeAttr)); //__out LPVOID lpFileInformation -// -// assert(::CompareFileTime(&debugeAttr.ftCreationTime, &infoFileIn.ftCreationTime) == 0); -// assert(::CompareFileTime(&debugeAttr.ftLastWriteTime, &infoFileIn.ftLastWriteTime) == 0); -// } -//#endif -// -// guardTarget.Dismiss(); -// -// /* -// //create test sparse file -// HANDLE hSparse = ::CreateFile(L"C:\\sparse.file", -// GENERIC_READ | GENERIC_WRITE, //read access required for FSCTL_SET_COMPRESSION -// FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, -// 0, -// CREATE_NEW, -// FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); -// DWORD br = 0; -// if (!::DeviceIoControl(hSparse, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &br,NULL)) -// throw 1; -// -// LARGE_INTEGER liDistanceToMove = {}; -// liDistanceToMove.QuadPart = 1024 * 1024 * 1024; //create 5 TB sparse file -// liDistanceToMove.QuadPart *= 5 * 1024; // -// if (!::SetFilePointerEx(hSparse, liDistanceToMove, NULL, FILE_BEGIN)) -// throw 1; -// -// if (!SetEndOfFile(hSparse)) -// throw 1; -// -// FILE_ZERO_DATA_INFORMATION zeroInfo = {}; -// zeroInfo.BeyondFinalZero.QuadPart = liDistanceToMove.QuadPart; -// if (!::DeviceIoControl(hSparse, FSCTL_SET_ZERO_DATA, &zeroInfo, sizeof(zeroInfo), NULL, 0, &br, NULL)) -// throw 1; -// -// ::CloseHandle(hSparse); -// */ -//} -#endif - -#ifdef FFS_LINUX -void rawCopyStream(const Zstring& sourceFile, - const Zstring& targetFile, - CallbackCopyFile* callback, - FileAttrib* sourceAttr) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting -{ - Loki::ScopeGuard guardTarget = Loki::MakeGuard(&removeFile, targetFile); //transactional behavior: place guard before lifetime of FileOutput - try - { - //open sourceFile for reading - FileInput fileIn(sourceFile); //throw FileError - - //create targetFile and open it for writing - FileOutput fileOut(targetFile, FileOutput::ACC_CREATE_NEW); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting - - static boost::thread_specific_ptr<std::vector<char>> cpyBuf; - if (!cpyBuf.get()) - cpyBuf.reset(new std::vector<char>(512 * 1024)); //512 kb seems to be a reasonable buffer size - std::vector<char>& buffer = *cpyBuf; - - //copy contents of sourceFile to targetFile - UInt64 totalBytesTransferred; - do - { - const size_t bytesRead = fileIn.read(&buffer[0], buffer.size()); //throw FileError - - fileOut.write(&buffer[0], bytesRead); //throw FileError - - totalBytesTransferred += bytesRead; - - //invoke callback method to update progress indicators - if (callback) - callback->updateCopyStatus(totalBytesTransferred); - } - while (!fileIn.eof()); - } - catch (ErrorTargetExisting&) - { - guardTarget.Dismiss(); //don't delete file that existed previously! - throw; - } - - //adapt file modification time: - { - struct stat srcInfo = {}; - if (::stat(sourceFile.c_str(), &srcInfo) != 0) //read file attributes from source directory - throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); - - if (sourceAttr) - { - sourceAttr->fileSize = UInt64(srcInfo.st_size); - sourceAttr->modificationTime = srcInfo.st_mtime; - } - - struct utimbuf newTimes = {}; - newTimes.actime = srcInfo.st_atime; - newTimes.modtime = srcInfo.st_mtime; - - //set new "last write time" - if (::utime(targetFile.c_str(), &newTimes) != 0) - throw FileError(_("Error changing modification time:") + "\n\"" + targetFile + "\"" + "\n\n" + getLastErrorFormatted()); - } - - guardTarget.Dismiss(); //target has been created successfully! -} -#endif - - -inline -void copyFileImpl(const Zstring& sourceFile, - const Zstring& targetFile, - CallbackCopyFile* callback, - FileAttrib* sourceAttr) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked -{ -#ifdef FFS_WIN - /* - rawCopyWinApi() rawCopyWinOptimized() - ------------------------------------- - Attributes YES YES - Filetimes YES YES - ADS YES YES - Encrypted YES YES - Compressed NO YES - Sparse NO YES - PERF - 6% faster - SAMBA, ect. YES UNKNOWN! -> issues writing ADS to Samba, issues reading from NAS, error copying files having "blocked" state... ect. damn! - */ - - rawCopyWinApi(sourceFile, targetFile, callback, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked - //rawCopyWinOptimized(sourceFile, targetFile, callback); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked ->about 8% faster - -#elif defined FFS_LINUX - rawCopyStream(sourceFile, targetFile, callback, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting -#endif -} -} - - -void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPathMissing, ErrorFileLocked - const Zstring& targetFile, - bool copyFilePermissions, - bool transactionalCopy, - CallbackCopyFile* callback, - FileAttrib* sourceAttr) -{ - if (transactionalCopy) - { - Zstring temporary = targetFile + zen::TEMP_FILE_ENDING; //use temporary file until a correct date has been set - Loki::ScopeGuard guardTempFile = Loki::MakeGuard([&]() { removeFile(temporary); }); //transactional behavior: ensure cleanup (e.g. network drop) -> ref to temporary[!] - - //raw file copy - try - { - copyFileImpl(sourceFile, temporary, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked - } - catch (ErrorTargetExisting&) - { - //determine non-used temp file name "first": - //using optimistic strategy: assume everything goes well, but recover on error -> minimize file accesses - temporary = createTempName(targetFile); - - //retry - copyFileImpl(sourceFile, temporary, callback, sourceAttr); //throw FileError - } - - //have target file deleted (after read access on source and target has been confirmed) => allow for almost transactional overwrite - if (callback) - callback->deleteTargetFile(targetFile); - - //rename temporary file: - //perf: this call is REALLY expensive on unbuffered volumes! ~40% performance decrease on FAT USB stick! - renameFile(temporary, targetFile); //throw FileError - - guardTempFile.Dismiss(); - } - else - { - //have target file deleted - if (callback) callback->deleteTargetFile(targetFile); - - copyFileImpl(sourceFile, targetFile, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked - } - /* - Note: non-transactional file copy solves at least four problems: - -> skydrive - doesn't allow for .ffs_tmp extension and returns ERROR_INVALID_PARAMETER - -> network renaming issues - -> allow for true delete before copy to handle low disk space problems - -> higher performance on non-buffered drives (e.g. usb sticks) - */ - - //set file permissions - if (copyFilePermissions) - { - Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(&removeFile, targetFile); - copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError - guardTargetFile.Dismiss(); //target has been created successfully! - } -} diff --git a/shared/file_handling.h b/shared/file_handling.h deleted file mode 100644 index f1ed2d98..00000000 --- a/shared/file_handling.h +++ /dev/null @@ -1,120 +0,0 @@ -// ************************************************************************** -// * 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 FILE_HANDLING_H_INCLUDED -#define FILE_HANDLING_H_INCLUDED - -#include "zstring.h" -#include "file_error.h" -#include "int64.h" - -namespace zen -{ -struct CallbackRemoveDir; -struct CallbackMoveFile; -struct CallbackCopyFile; - - -bool fileExists (const Zstring& filename); //throw() replaces wxFileExists() -bool dirExists (const Zstring& dirname); //throw() replaces wxDirExists() -bool symlinkExists (const Zstring& objname); //throw() check whether a symbolic link exists -bool somethingExists(const Zstring& objname); //throw() check whether any object with this name exists - -//check whether two folders are located on the same (logical) volume -//left and right directories NEED NOT yet exist! volume prefix is sufficient! path may end with PATH_SEPARATOR -enum ResponseSame -{ - IS_SAME_YES, - IS_SAME_NO, - IS_SAME_CANT_SAY -}; -ResponseSame onSameVolume(const Zstring& folderLeft, const Zstring& folderRight); //throw() - -enum ProcSymlink -{ - SYMLINK_DIRECT, - SYMLINK_FOLLOW -}; - -Int64 getFileTime(const Zstring& filename, ProcSymlink procSl); //throw FileError -void setFileTime(const Zstring& filename, const Int64& modificationTime, ProcSymlink procSl); //throw FileError - -//symlink handling: always evaluate target -UInt64 getFilesize(const Zstring& filename); //throw FileError - -//file handling -bool removeFile(const Zstring& filename); //return "true" if file was actually deleted; throw (FileError) -void removeDirectory(const Zstring& directory, CallbackRemoveDir* callback = NULL); //throw FileError - - -//rename file or directory: no copying!!! -void renameFile(const Zstring& oldName, const Zstring& newName); //throw FileError; - -//move source to target; expectations: all super-directories of target exist -//"ignoreExisting": if target already exists, source is deleted -void moveFile(const Zstring& sourceFile, const Zstring& targetFile, bool ignoreExisting, CallbackMoveFile* callback); //throw FileError; - -//move source to target including subdirectories -//"ignoreExisting": existing directories and files will be enriched -void moveDirectory(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExisting, CallbackMoveFile* callback); //throw FileError; - -//creates superdirectories automatically: -void createDirectory(const Zstring& directory, const Zstring& templateDir, bool copyFilePermissions); //throw FileError; -void createDirectory(const Zstring& directory); //throw FileError; -> function overload avoids default parameter ambiguity issues! - -struct FileAttrib -{ - UInt64 fileSize; - Int64 modificationTime; //size_t UTC compatible -}; - -void copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPathMissing, ErrorFileLocked (Windows-only) - const Zstring& targetFile, //symlink handling: dereference source - bool copyFilePermissions, - bool transactionalCopy, - CallbackCopyFile* callback, //may be NULL - FileAttrib* sourceAttr = NULL); //return current attributes at the time of copy -//Note: it MAY happen that copyFile() leaves temp files behind, e.g. temporary network drop. -// => clean them up at an appropriate time (automatically set sync directions to delete them). They have the following ending: -const Zstring TEMP_FILE_ENDING = Zstr(".ffs_tmp"); - -void copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool copyFilePermissions); //throw FileError - - - - -//----------- callbacks --------------- -struct CallbackRemoveDir -{ - virtual ~CallbackRemoveDir() {} - virtual void notifyFileDeletion(const Zstring& filename) = 0; - virtual void notifyDirDeletion(const Zstring& dirname) = 0; -}; - - -struct CallbackCopyFile //callback functionality -{ - virtual ~CallbackCopyFile() {} - - //if target is existing user needs to implement deletion: copyFile() NEVER deletes target if already existing! - //at this point full read access on source had been proven, so it's safe to delete it. - virtual void deleteTargetFile(const Zstring& targetFile) = 0; //may throw exceptions - - //may throw: - //Linux: unconditionally - //Windows: first exception is swallowed, requestUiRefresh() is then called again where it should throw again and exception will propagate as expected - virtual void updateCopyStatus(UInt64 totalBytesTransferred) = 0; -}; - - -struct CallbackMoveFile //callback functionality -{ - virtual ~CallbackMoveFile() {} - virtual void requestUiRefresh(const Zstring& currentObject) = 0; //see CallbackCopyFile! -}; -} - -#endif //FILE_HANDLING_H_INCLUDED diff --git a/shared/file_id.cpp b/shared/file_id.cpp deleted file mode 100644 index 198598b4..00000000 --- a/shared/file_id.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************** -// * 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 "file_id.h" -#include "file_id_internal.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" -#include "loki/ScopeGuard.h" - -#elif defined FFS_LINUX -#include <sys/stat.h> -#endif - - -std::string util::retrieveFileID(const Zstring& filename) -{ -#ifdef FFS_WIN - //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 - - const HANDLE hFile = ::CreateFile(zen::applyLongPathPrefix(filename).c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory - NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hFile)); - - BY_HANDLE_FILE_INFORMATION fileInfo = {}; - if (::GetFileInformationByHandle(hFile, &fileInfo)) - return extractFileID(fileInfo); - } - -#elif defined FFS_LINUX - struct stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) == 0) //lstat() does not follow symlinks - return extractFileID(fileInfo); -#endif - - assert(false); - return std::string(); -} - - -bool util::sameFileSpecified(const Zstring& file1, const Zstring& file2) -{ - if (EqualFilename()(file1, file2)) //quick check - return true; - - const std::string id1 = retrieveFileID(file1); - const std::string id2 = retrieveFileID(file2); - - if (id1.empty() || id2.empty()) - return false; - - return id1 == id2; -} diff --git a/shared/file_id.h b/shared/file_id.h deleted file mode 100644 index eaf47e3c..00000000 --- a/shared/file_id.h +++ /dev/null @@ -1,28 +0,0 @@ -// ************************************************************************** -// * 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 FILEID_H_INCLUDED -#define FILEID_H_INCLUDED - -#include "zstring.h" -#include <string> - - - -//unique file identifier -namespace util -{ -//get unique file id (symbolic link handling: opens the link!!!) -//returns empty string on error! -std::string retrieveFileID(const Zstring& filename); - -//test whether two distinct paths point to the same file or directory: -// true: paths point to same files/dirs -// false: error occurred OR point to different files/dirs -bool sameFileSpecified(const Zstring& file1, const Zstring& file2); -} - -#endif // FILEID_H_INCLUDED diff --git a/shared/file_id_internal.h b/shared/file_id_internal.h deleted file mode 100644 index a8a7042d..00000000 --- a/shared/file_id_internal.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************** -// * 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 FILE_ID_INTERNAL_HEADER_013287632486321493 -#define FILE_ID_INTERNAL_HEADER_013287632486321493 - -#include <string> - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" - -#elif defined FFS_LINUX -#include <sys/stat.h> -#endif - -namespace -{ -template <class T> inline -std::string numberToBytes(T number) -{ - const char* rawBegin = reinterpret_cast<const char*>(&number); - return std::string(rawBegin, rawBegin + sizeof(number)); -} - -#ifdef FFS_WIN -inline -std::string extractFileID(const BY_HANDLE_FILE_INFORMATION& fileInfo) -{ - return numberToBytes(fileInfo.dwVolumeSerialNumber) + - numberToBytes(fileInfo.nFileIndexHigh) + - numberToBytes(fileInfo.nFileIndexLow); -} -#elif defined FFS_LINUX -inline -std::string extractFileID(const struct stat& fileInfo) -{ - return numberToBytes(fileInfo.st_dev) + - numberToBytes(fileInfo.st_ino); -} -#endif - -} - - -#endif //FILE_ID_INTERNAL_HEADER_013287632486321493 diff --git a/shared/file_io.cpp b/shared/file_io.cpp deleted file mode 100644 index 59b78044..00000000 --- a/shared/file_io.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// ************************************************************************** -// * 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 "file_io.h" -#include "last_error.h" -#include "i18n.h" - -#ifdef FFS_WIN -#include "long_path_prefix.h" -#elif defined FFS_LINUX -#include <cerrno> -#endif - -using namespace zen; - - -FileInput::FileInput(FileHandle handle, const Zstring& filename) : - eofReached(false), - fileHandle(handle), - filename_(filename) {} - - -FileInput::FileInput(const Zstring& filename) : //throw FileError, ErrorNotExisting - eofReached(false), - filename_(filename) -{ -#ifdef FFS_WIN - fileHandle = ::CreateFile(zen::applyLongPathPrefix(filename).c_str(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //all shared modes are required to read open files that are shared by other applications - 0, - OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, - /* possible values: (Reference http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx#caching_behavior) - FILE_FLAG_NO_BUFFERING - FILE_FLAG_RANDOM_ACCESS - FILE_FLAG_SEQUENTIAL_SCAN - - tests on Win7 x64 show that FILE_FLAG_SEQUENTIAL_SCAN provides best performance for binary comparison in all cases: - - comparing different physical disks (DVD <-> HDD and HDD <-> HDD) - - even on same physical disk! (HDD <-> HDD) - - independent from client buffer size! - - tests on XP show that FILE_FLAG_SEQUENTIAL_SCAN provides best performance for binary comparison when - - comparing different physical disks (DVD <-> HDD) - - while FILE_FLAG_RANDOM_ACCESS offers best performance for - - same physical disk (HDD <-> HDD) - - Problem: bad XP implementation of prefetch makes flag FILE_FLAG_SEQUENTIAL_SCAN effectively load two files at once from one drive - swapping every 64 kB (or similar). File access times explode! - => For XP it is critical to use FILE_FLAG_RANDOM_ACCESS (to disable prefetch) if reading two files on same disk and - FILE_FLAG_SEQUENTIAL_SCAN when reading from different disk (e.g. massive performance improvement compared to random access for DVD <-> HDD!) - => there is no compromise that satisfies all cases! (on XP) - - for FFS most comparisons are probably between different disks => let's use FILE_FLAG_SEQUENTIAL_SCAN - */ - NULL); - if (fileHandle == INVALID_HANDLE_VALUE) - { - const DWORD lastError = ::GetLastError(); - - std::wstring errorMessage = _("Error opening file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted(lastError); - - if (lastError == ERROR_FILE_NOT_FOUND || - lastError == ERROR_PATH_NOT_FOUND) - throw ErrorNotExisting(errorMessage); - - throw FileError(errorMessage); - } - -#elif defined FFS_LINUX - fileHandle = ::fopen(filename.c_str(), "r,type=record,noseek"); //utilize UTF-8 filename - if (fileHandle == NULL) - { - const int lastError = errno; - - std::wstring errorMessage = _("Error opening file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted(lastError); - - if (lastError == ENOENT) - throw ErrorNotExisting(errorMessage); - - throw FileError(errorMessage); - } -#endif -} - - -FileInput::~FileInput() -{ -#ifdef FFS_WIN - ::CloseHandle(fileHandle); -#elif defined FFS_LINUX - ::fclose(fileHandle); //NEVER allow passing NULL to fclose! -> crash!; fileHandle != NULL in this context! -#endif -} - - -size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number of bytes read; throw (FileError) -{ -#ifdef FFS_WIN - 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 -#elif defined FFS_LINUX - const size_t bytesRead = ::fread(buffer, 1, bytesToRead, fileHandle); - if (::ferror(fileHandle) != 0) -#endif - throw FileError(_("Error reading file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted() + " (r)"); - -#ifdef FFS_WIN - if (bytesRead < bytesToRead) //falsify only! -#elif defined FFS_LINUX - if (::feof(fileHandle) != 0) -#endif - eofReached = true; - - if (bytesRead > bytesToRead) - throw FileError(_("Error reading file:") + "\n\"" + filename_ + "\"" + "\n\n" + "buffer overflow"); - - return bytesRead; -} - - -bool FileInput::eof() //end of file reached -{ - return eofReached; -} - - -FileOutput::FileOutput(FileHandle handle, const Zstring& filename) : fileHandle(handle), filename_(filename) {} - - -FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting - filename_(filename) -{ -#ifdef FFS_WIN - fileHandle = ::CreateFile(zen::applyLongPathPrefix(filename).c_str(), - GENERIC_READ | GENERIC_WRITE, - /* http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx - quote: When an application creates a file across a network, it is better - to use GENERIC_READ | GENERIC_WRITE for dwDesiredAccess than to use GENERIC_WRITE alone. - The resulting code is faster, because the redirector can use the cache manager and send fewer SMBs with more data. - This combination also avoids an issue where writing to a file across a network can occasionally return ERROR_ACCESS_DENIED. */ - FILE_SHARE_READ | FILE_SHARE_DELETE, //note: FILE_SHARE_DELETE is required to rename file while handle is open! - 0, - access == ACC_OVERWRITE ? CREATE_ALWAYS : CREATE_NEW, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (fileHandle == INVALID_HANDLE_VALUE) - { - const DWORD lastError = ::GetLastError(); - std::wstring errorMessage = _("Error writing file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted(lastError); - - if (lastError == ERROR_FILE_EXISTS) - throw ErrorTargetExisting(errorMessage); - - if (lastError == ERROR_PATH_NOT_FOUND) - throw ErrorTargetPathMissing(errorMessage); - - throw FileError(errorMessage); - } - -#elif defined FFS_LINUX - fileHandle = ::fopen(filename.c_str(), - //GNU extension: https://www.securecoding.cert.org/confluence/display/cplusplus/FIO03-CPP.+Do+not+make+assumptions+about+fopen()+and+file+creation - access == ACC_OVERWRITE ? "w,type=record,noseek" : "wx,type=record,noseek"); - if (fileHandle == NULL) - { - const int lastError = errno; - std::wstring errorMessage = _("Error writing file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted(lastError); - if (lastError == EEXIST) - throw ErrorTargetExisting(errorMessage); - - if (lastError == ENOENT) - throw ErrorTargetPathMissing(errorMessage); - - throw FileError(errorMessage); - } -#endif -} - - -FileOutput::~FileOutput() -{ -#ifdef FFS_WIN - ::CloseHandle(fileHandle); -#elif defined FFS_LINUX - ::fclose(fileHandle); //NEVER allow passing NULL to fclose! -> crash! -#endif -} - - -void FileOutput::write(const void* buffer, size_t bytesToWrite) //throw FileError -{ -#ifdef FFS_WIN - DWORD bytesWritten = 0; - if (!::WriteFile(fileHandle, //__in HANDLE hFile, - buffer, //__out LPVOID lpBuffer, - static_cast<DWORD>(bytesToWrite), //__in DWORD nNumberOfBytesToWrite, - &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten, - NULL)) //__inout_opt LPOVERLAPPED lpOverlapped -#elif defined FFS_LINUX - const size_t bytesWritten = ::fwrite(buffer, 1, bytesToWrite, fileHandle); - if (::ferror(fileHandle) != 0) -#endif - throw FileError(_("Error writing file:") + "\n\"" + filename_ + "\"" + "\n\n" + zen::getLastErrorFormatted() + " (w)"); //w -> distinguish from fopen error message! - - if (bytesWritten != bytesToWrite) //must be fulfilled for synchronous writes! - throw FileError(_("Error writing file:") + "\n\"" + filename_ + "\"" + "\n\n" + "incomplete write"); -} diff --git a/shared/file_io.h b/shared/file_io.h deleted file mode 100644 index 76713e5b..00000000 --- a/shared/file_io.h +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************** -// * 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 FILEIO_H_INCLUDED -#define FILEIO_H_INCLUDED - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#elif defined FFS_LINUX -#include <cstdio> -#endif - -#include "zstring.h" -#include "file_error.h" - -namespace zen -{ -//file IO optimized for sequential read/write accesses + better error reporting + long path support (following symlinks) - -#ifdef FFS_WIN -typedef HANDLE FileHandle; -#elif defined FFS_LINUX -typedef FILE* FileHandle; -#endif - -class FileInput -{ -public: - FileInput(const Zstring& filename); //throw FileError, ErrorNotExisting - FileInput(FileHandle handle, const Zstring& filename); //takes ownership! - ~FileInput(); - - size_t read(void* buffer, size_t bytesToRead); //throw FileError; returns actual number of bytes read - bool eof(); //end of file reached - -private: - FileInput(const FileInput&); - FileInput& operator=(const FileInput&); - - bool eofReached; - FileHandle fileHandle; - const Zstring filename_; -}; - - -class FileOutput -{ -public: - enum AccessFlag - { - ACC_OVERWRITE, - ACC_CREATE_NEW - }; - FileOutput(const Zstring& filename, AccessFlag access); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting - FileOutput(FileHandle handle, const Zstring& filename); //takes ownership! - ~FileOutput(); - - void write(const void* buffer, size_t bytesToWrite); //throw FileError - -private: - FileOutput(const FileOutput&); - FileOutput& operator=(const FileOutput&); - - FileHandle fileHandle; - const Zstring filename_; -}; - -} - -#endif // FILEIO_H_INCLUDED diff --git a/shared/file_traverser.cpp b/shared/file_traverser.cpp deleted file mode 100644 index eb79b0e7..00000000 --- a/shared/file_traverser.cpp +++ /dev/null @@ -1,613 +0,0 @@ -// ************************************************************************** -// * 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 "file_traverser.h" -#include <limits> -#include "last_error.h" -#include "assert_static.h" -#include "symlink_target.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" -#include "dst_hack.h" -#include "file_update_handle.h" -#include "dll_loader.h" -#include "FindFilePlus/find_file_plus.h" - -#elif defined FFS_LINUX -#include <sys/stat.h> -#include <dirent.h> -#include <cerrno> -#endif - -using namespace zen; - - -namespace -{ -//implement "retry" in a generic way: - -//returns "true" if "cmd" was invoked successfully, "false" if error occured and was ignored -template <class Command> inline //function object with bool operator()(std::wstring& errorMsg), returns "true" on success, "false" on error and writes "errorMsg" in this case -bool tryReportingError(Command cmd, zen::TraverseCallback& callback) -{ - for (;;) - { - std::wstring errorMsg; - if (cmd(errorMsg)) - return true; - - switch (callback.onError(errorMsg)) - { - case TraverseCallback::TRAV_ERROR_RETRY: - break; - case TraverseCallback::TRAV_ERROR_IGNORE: - return false; - default: - assert(false); - break; - } - } -} - - -#ifdef FFS_WIN -inline -bool setWin32FileInformationFromSymlink(const Zstring& linkName, zen::TraverseCallback::FileInfo& output) -{ - //open handle to target of symbolic link - HANDLE hFile = ::CreateFile(zen::applyLongPathPrefix(linkName).c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - return false; - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hFile)); - - BY_HANDLE_FILE_INFORMATION fileInfoByHandle = {}; - if (!::GetFileInformationByHandle(hFile, &fileInfoByHandle)) - return false; - - //write output - output.lastWriteTimeRaw = toTimeT(fileInfoByHandle.ftLastWriteTime); - output.fileSize = zen::UInt64(fileInfoByHandle.nFileSizeLow, fileInfoByHandle.nFileSizeHigh); - return true; -} - -/* -warn_static("finish") - util::DllFun<findplus::OpenDirFunc> openDir (findplus::getDllName(), findplus::openDirFuncName); - util::DllFun<findplus::ReadDirFunc> readDir (findplus::getDllName(), findplus::readDirFuncName); - util::DllFun<findplus::CloseDirFunc> closeDir(findplus::getDllName(), findplus::closeDirFuncName); -*/ -#endif -} - - -class DirTraverser -{ -public: - DirTraverser(const Zstring& baseDirectory, bool followSymlinks, zen::TraverseCallback& sink, zen::DstHackCallback* dstCallback) -#ifdef FFS_WIN - : isFatFileSystem(dst::isFatDrive(baseDirectory)) -#endif - { -#ifdef FFS_WIN - //format base directory name - const Zstring& directoryFormatted = baseDirectory; - -#elif defined FFS_LINUX - const Zstring directoryFormatted = //remove trailing slash - baseDirectory.size() > 1 && baseDirectory.EndsWith(FILE_NAME_SEPARATOR) ? //exception: allow '/' - baseDirectory.BeforeLast(FILE_NAME_SEPARATOR) : - baseDirectory; -#endif - - //traverse directories - if (followSymlinks) - traverse<true>(directoryFormatted, sink, 0); - else - traverse<false>(directoryFormatted, sink, 0); - - //apply daylight saving time hack AFTER file traversing, to give separate feedback to user -#ifdef FFS_WIN - if (isFatFileSystem && dstCallback) - applyDstHack(*dstCallback); -#endif - } - -private: - DirTraverser(const DirTraverser&); - DirTraverser& operator=(const DirTraverser&); - - template <bool followSymlinks> - void traverse(const Zstring& directory, zen::TraverseCallback& sink, int level) - { - tryReportingError([&](std::wstring& errorMsg) -> bool - { - if (level == 100) //notify endless recursion - { - errorMsg = _("Endless loop when traversing directory:") + "\n\"" + directory + "\""; - return false; - } - return true; - }, sink); - -#ifdef FFS_WIN -/* - //ensure directoryPf ends with backslash - const Zstring& directoryPf = directory.EndsWith(FILE_NAME_SEPARATOR) ? - directory : - directory + FILE_NAME_SEPARATOR; - - FindHandle searchHandle = NULL; - tryReportingError([&](std::wstring& errorMsg) -> bool - { - searchHandle = this->openDir(applyLongPathPrefix(directoryPf).c_str()); - //no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH - - if (searchHandle == NULL) - { - //const DWORD lastError = ::GetLastError(); - //if (lastError == ERROR_FILE_NOT_FOUND) -> actually NOT okay, even for an empty directory this should not occur (., ..) - //return true; //fine: empty directory - - //else: we have a problem... report it: - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - return true; - }, sink); - - if (searchHandle == NULL) - return; //empty dir or ignore error - LOKI_ON_BLOCK_EXIT2(this->closeDir(searchHandle)); - - FileInformation fileInfo = {}; - for (;;) - { - bool moreData = false; - tryReportingError([&](std::wstring& errorMsg) -> bool - { - if (!this->readDir(searchHandle, fileInfo)) - { - if (::GetLastError() == ERROR_NO_MORE_FILES) //this is fine - return true; - - //else we have a problem... report it: - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - - moreData = true; - return true; - }, sink); - if (!moreData) //no more items or ignore error - return; - - - //don't return "." and ".." - const Zchar* const shortName = fileInfo.shortName; - if (shortName[0] == L'.' && - (shortName[1] == L'\0' || (shortName[1] == L'.' && shortName[2] == L'\0'))) - continue; - - const Zstring& fullName = directoryPf + shortName; - - const bool isSymbolicLink = (fileInfo.fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0; - - if (isSymbolicLink && !followSymlinks) //evaluate symlink directly - { - TraverseCallback::SymlinkInfo details; - try - { - details.targetPath = getSymlinkRawTargetString(fullName); //throw FileError - } - catch (FileError& e) - { - (void)e; -#ifndef NDEBUG //show broken symlink / access errors in debug build! - sink.onError(e.msg()); -#endif - } - - details.lastWriteTimeRaw = toTimeT(fileInfo.lastWriteTime); - details.dirLink = (fileInfo.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; //directory symlinks have this flag on Windows - sink.onSymlink(shortName, fullName, details); - } - else if (fileInfo.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) //a directory... or symlink that needs to be followed (for directory symlinks this flag is set too!) - { - const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName); - switch (rv.returnCode) - { - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE: - break; - - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE: - traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1); - break; - } - } - else //a file or symlink that is followed... - { - TraverseCallback::FileInfo details; - - if (isSymbolicLink) //dereference symlinks! - { - if (!setWin32FileInformationFromSymlink(fullName, details)) - { - //broken symlink... - details.lastWriteTimeRaw = 0; //we are not interested in the modification time of the link - details.fileSize = 0U; - } - } - else - { - //####################################### DST hack ########################################### - if (isFatFileSystem) - { - const dst::RawTime rawTime(fileInfo.creationTime, fileInfo.lastWriteTime); - - if (dst::fatHasUtcEncoded(rawTime)) //throw (std::runtime_error) - fileInfo.lastWriteTime = dst::fatDecodeUtcTime(rawTime); //return real UTC time; throw (std::runtime_error) - else - markForDstHack.push_back(std::make_pair(fullName, fileInfo.lastWriteTime)); - } - //####################################### DST hack ########################################### - - details.lastWriteTimeRaw = toTimeT(fileInfo.lastWriteTime); - details.fileSize = fileInfo.fileSize.QuadPart; - } - - sink.onFile(shortName, fullName, details); - } - } -*/ - - - - //ensure directoryPf ends with backslash - const Zstring& directoryPf = directory.EndsWith(FILE_NAME_SEPARATOR) ? - directory : - directory + FILE_NAME_SEPARATOR; - WIN32_FIND_DATA fileInfo = {}; - - HANDLE searchHandle = INVALID_HANDLE_VALUE; - tryReportingError([&](std::wstring& errorMsg) -> bool - { - searchHandle = ::FindFirstFile(applyLongPathPrefix(directoryPf + L'*').c_str(), &fileInfo); - //no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH - - if (searchHandle == INVALID_HANDLE_VALUE) - { - //const DWORD lastError = ::GetLastError(); - //if (lastError == ERROR_FILE_NOT_FOUND) -> actually NOT okay, even for an empty directory this should not occur (., ..) - //return true; //fine: empty directory - - //else: we have a problem... report it: - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - return true; - }, sink); - - if (searchHandle == INVALID_HANDLE_VALUE) - return; //empty dir or ignore error - LOKI_ON_BLOCK_EXIT2(::FindClose(searchHandle)); - - do - { - //don't return "." and ".." - const Zchar* const shortName = fileInfo.cFileName; - if (shortName[0] == L'.' && - (shortName[1] == L'\0' || (shortName[1] == L'.' && shortName[2] == L'\0'))) - continue; - - const Zstring& fullName = directoryPf + shortName; - - const bool isSymbolicLink = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0; - - if (isSymbolicLink && !followSymlinks) //evaluate symlink directly - { - TraverseCallback::SymlinkInfo details; - try - { - details.targetPath = getSymlinkRawTargetString(fullName); //throw FileError - } - catch (FileError& e) - { - (void)e; - #ifndef NDEBUG //show broken symlink / access errors in debug build! - sink.onError(e.msg()); - #endif - } - - details.lastWriteTimeRaw = toTimeT(fileInfo.ftLastWriteTime); - details.dirLink = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; //directory symlinks have this flag on Windows - sink.onSymlink(shortName, fullName, details); - } - else if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //a directory... or symlink that needs to be followed (for directory symlinks this flag is set too!) - { - const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName); - switch (rv.returnCode) - { - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE: - break; - - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE: - traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1); - break; - } - } - else //a file or symlink that is followed... - { - TraverseCallback::FileInfo details; - - if (isSymbolicLink) //dereference symlinks! - { - if (!setWin32FileInformationFromSymlink(fullName, details)) - { - //broken symlink... - details.lastWriteTimeRaw = 0; //we are not interested in the modification time of the link - details.fileSize = 0U; - } - } - else - { - //####################################### DST hack ########################################### - if (isFatFileSystem) - { - const dst::RawTime rawTime(fileInfo.ftCreationTime, fileInfo.ftLastWriteTime); - - if (dst::fatHasUtcEncoded(rawTime)) //throw (std::runtime_error) - fileInfo.ftLastWriteTime = dst::fatDecodeUtcTime(rawTime); //return real UTC time; throw (std::runtime_error) - else - markForDstHack.push_back(std::make_pair(fullName, fileInfo.ftLastWriteTime)); - } - //####################################### DST hack ########################################### - details.lastWriteTimeRaw = toTimeT(fileInfo.ftLastWriteTime); - details.fileSize = zen::UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh); - } - - sink.onFile(shortName, fullName, details); - } - } - while ([&]() -> bool - { - bool moreData = false; - - tryReportingError([&](std::wstring& errorMsg) -> bool - { - if (!::FindNextFile(searchHandle, // handle to search - &fileInfo)) // pointer to structure for data on found file - { - if (::GetLastError() == ERROR_NO_MORE_FILES) //this is fine - return true; - - //else we have a problem... report it: - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - - moreData = true; - return true; - }, sink); - - return moreData; - }()); - -#elif defined FFS_LINUX - DIR* dirObj = NULL; - if (!tryReportingError([&](std::wstring& errorMsg) -> bool - { - dirObj = ::opendir(directory.c_str()); //directory must NOT end with path separator, except "/" - if (dirObj == NULL) - { - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - return true; - }, sink)) - return; - LOKI_ON_BLOCK_EXIT2(::closedir(dirObj)); //never close NULL handles! -> crash - - while (true) - { - struct dirent* dirEntry = NULL; - tryReportingError([&](std::wstring& errorMsg) -> bool - { - errno = 0; //set errno to 0 as unfortunately this isn't done when readdir() returns NULL because it can't find any files - dirEntry = ::readdir(dirObj); - if (dirEntry == NULL) - { - if (errno == 0) - return true; //everything okay, not more items - - //else: we have a problem... report it: - errorMsg = _("Error traversing directory:") + "\n\"" + directory + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - return true; - }, sink); - if (dirEntry == NULL) //no more items or ignore error - return; - - - //don't return "." and ".." - const char* const shortName = dirEntry->d_name; - if (shortName[0] == '.' && - (shortName[1] == '\0' || (shortName[1] == '.' && shortName[2] == '\0'))) - continue; - - const Zstring& fullName = directory.EndsWith(FILE_NAME_SEPARATOR) ? //e.g. "/" - directory + shortName : - directory + FILE_NAME_SEPARATOR + shortName; - - struct stat fileInfo = {}; - - if (!tryReportingError([&](std::wstring& errorMsg) -> bool - { - if (::lstat(fullName.c_str(), &fileInfo) != 0) //lstat() does not resolve symlinks - { - errorMsg = _("Error reading file attributes:") + "\n\"" + fullName + "\"" + "\n\n" + zen::getLastErrorFormatted(); - return false; - } - return true; - }, sink)) - continue; //ignore error: skip file - - const bool isSymbolicLink = S_ISLNK(fileInfo.st_mode); - - if (isSymbolicLink) - { - if (followSymlinks) //on Linux Symlinks need to be followed to evaluate whether they point to a file or directory - { - if (::stat(fullName.c_str(), &fileInfo) != 0) //stat() resolves symlinks - { - sink.onFile(shortName, fullName, TraverseCallback::FileInfo()); //report broken symlink as file! - continue; - } - } - else //evaluate symlink directly - { - TraverseCallback::SymlinkInfo details; - try - { - details.targetPath = getSymlinkRawTargetString(fullName); //throw FileError - } - catch (FileError& e) - { -#ifndef NDEBUG //show broken symlink / access errors in debug build! - sink.onError(e.msg()); -#endif - } - - details.lastWriteTimeRaw = fileInfo.st_mtime; //UTC time(ANSI C format); unit: 1 second - details.dirLink = ::stat(fullName.c_str(), &fileInfo) == 0 && S_ISDIR(fileInfo.st_mode); //S_ISDIR and S_ISLNK are mutually exclusive on Linux => need to follow link - sink.onSymlink(shortName, fullName, details); - continue; - } - } - - //fileInfo contains dereferenced data in any case from here on - - if (S_ISDIR(fileInfo.st_mode)) //a directory... cannot be a symlink on Linux in this case - { - const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName); - switch (rv.returnCode) - { - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE: - break; - - case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE: - traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1); - break; - } - } - else //a file... (or symlink; pathological!) - { - TraverseCallback::FileInfo details; - details.lastWriteTimeRaw = fileInfo.st_mtime; //UTC time(ANSI C format); unit: 1 second - details.fileSize = zen::UInt64(fileInfo.st_size); - - sink.onFile(shortName, fullName, details); - } - } -#endif - } - - -#ifdef FFS_WIN - //####################################### DST hack ########################################### - void applyDstHack(zen::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); - - const dst::RawTime encodedTime = dst::fatEncodeUtcTime(i->second); //throw (std::runtime_error) - { - //may need to remove the readonly-attribute (e.g. FAT usb drives) - FileUpdateHandle updateHandle(i->first, [ = ]() - { - return ::CreateFile(zen::applyLongPathPrefix(i->first).c_str(), - GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - }); - if (updateHandle.get() == INVALID_HANDLE_VALUE) - { - ++failedAttempts; - assert(false); //don't throw exceptions due to dst hack here - continue; - } - - if (!::SetFileTime(updateHandle.get(), - &encodedTime.createTimeRaw, - NULL, - &encodedTime.writeTimeRaw)) - { - ++failedAttempts; - assert(false); //don't throw exceptions due to dst hack here - continue; - } - } - - //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 = {}; - ::GetFileAttributesEx(zen::applyLongPathPrefix(i->first).c_str(), //__in LPCTSTR lpFileName, - GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId, - &debugeAttr); //__out LPVOID lpFileInformation - - 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; - } - } - } - } - - const bool isFatFileSystem; - typedef std::vector<std::pair<Zstring, FILETIME> > FilenameTimeList; - FilenameTimeList markForDstHack; - //####################################### DST hack ########################################### -#endif -}; - - -void zen::traverseFolder(const Zstring& directory, bool followSymlinks, TraverseCallback& sink, DstHackCallback* dstCallback) -{ -#ifdef FFS_WIN - try //traversing certain folders with restricted permissions requires this privilege! (but copying these files may still fail) - { - zen::Privileges::getInstance().ensureActive(SE_BACKUP_NAME); //throw FileError - } - catch (...) {} //don't cause issues in user mode -#endif - - DirTraverser(directory, followSymlinks, sink, dstCallback); -} diff --git a/shared/file_traverser.h b/shared/file_traverser.h deleted file mode 100644 index 7da86c3a..00000000 --- a/shared/file_traverser.h +++ /dev/null @@ -1,86 +0,0 @@ -// ************************************************************************** -// * 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 FILETRAVERSER_H_INCLUDED -#define FILETRAVERSER_H_INCLUDED - -#include "zstring.h" -#include "loki/TypeManip.h" -#include "int64.h" - -//advanced file traverser returning metadata and hierarchical information on files and directories - -namespace zen -{ -class TraverseCallback -{ -public: - virtual ~TraverseCallback() {} - - struct FileInfo - { - UInt64 fileSize; //unit: bytes! - Int64 lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC - }; - - struct SymlinkInfo - { - Int64 lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC - Zstring targetPath; //may be empty if something goes wrong - bool dirLink; //"true": point to dir; "false": point to file (or broken Link on Linux) - }; - - struct ReturnValDir - { - enum ReturnValueEnh - { - TRAVERSING_DIR_IGNORE, - TRAVERSING_DIR_CONTINUE - }; - - ReturnValDir(Loki::Int2Type<TRAVERSING_DIR_IGNORE>) : returnCode(TRAVERSING_DIR_IGNORE), subDirCb(NULL) {} - ReturnValDir(Loki::Int2Type<TRAVERSING_DIR_CONTINUE>, TraverseCallback& subDirCallback) : returnCode(TRAVERSING_DIR_CONTINUE), subDirCb(&subDirCallback) {} - - ReturnValueEnh returnCode; - TraverseCallback* subDirCb; - }; - - enum HandleError - { - TRAV_ERROR_RETRY, - TRAV_ERROR_IGNORE - }; - - //overwrite these virtual methods - virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) = 0; - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) = 0; - virtual ReturnValDir onDir (const Zchar* shortName, const Zstring& fullName) = 0; - virtual HandleError onError (const std::wstring& errorText) = 0; -}; - - -#ifdef FFS_WIN -struct DstHackCallback -{ - virtual ~DstHackCallback() {} - virtual void requestUiRefresh(const Zstring& filename) = 0; //applying DST hack imposes significant one-time performance drawback => callback to inform user -}; -#else -struct DstHackCallback; //DST hack not required on Linux -#endif - -//custom traverser with detail information about files -//directory may end with PATH_SEPARATOR -void traverseFolder(const Zstring& directory, //throw(); - bool followSymlinks, - TraverseCallback& sink, - DstHackCallback* dstCallback = NULL); //apply DST hack if callback is supplied -//followSymlinks: -//"true": Symlinks dereferenced and reported via onFile() and onDir() => onSymlink not used! -//"false": Symlinks directly reported via onSymlink(), directory symlinks are not followed -} - -#endif // FILETRAVERSER_H_INCLUDED diff --git a/shared/file_update_handle.h b/shared/file_update_handle.h deleted file mode 100644 index 1ffb7000..00000000 --- a/shared/file_update_handle.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef FILE_UPDATE_HANDLE_H_INCLUDED -#define FILE_UPDATE_HANDLE_H_INCLUDED - -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" - -namespace -{ -//manage file handle to update existing files (temporarily resetting read-only if necessary) -//CreateFileCmd: lambda directly returning non-owned file handle from ::CreateFile() -class FileUpdateHandle -{ -public: - template <class CreateFileCmd> - FileUpdateHandle(const Zstring& filename, CreateFileCmd cmd) : - filenameFmt(zen::applyLongPathPrefix(filename)), - hFile(INVALID_HANDLE_VALUE), - attr(INVALID_FILE_ATTRIBUTES) - { - hFile = cmd(); - if (hFile != INVALID_HANDLE_VALUE) - return; - - const DWORD lastError = ::GetLastError(); - if (lastError == ERROR_ACCESS_DENIED) //function fails if file is read-only - { - Loki::ScopeGuard guardErrorCode = Loki::MakeGuard(::SetLastError, lastError); //transactional behavior: ensure cleanup (e.g. network drop) -> cref [!] - - //read-only file attribute may cause trouble: temporarily reset it - const DWORD tmpAttr = ::GetFileAttributes(filenameFmt.c_str()); - if (tmpAttr != INVALID_FILE_ATTRIBUTES && (tmpAttr & FILE_ATTRIBUTE_READONLY)) - { - if (::SetFileAttributes(filenameFmt.c_str(), FILE_ATTRIBUTE_NORMAL)) - { - guardErrorCode.Dismiss(); - attr = tmpAttr; //"create" guard on read-only attribute - - //now try again - hFile = cmd(); - } - } - } - } - - ~FileUpdateHandle() - { - if (hFile != INVALID_HANDLE_VALUE) - ::CloseHandle(hFile); - - if (attr != INVALID_FILE_ATTRIBUTES) - ::SetFileAttributes(filenameFmt.c_str(), attr); - } - - //may return INVALID_FILE_ATTRIBUTES, in which case ::GetLastError() may be called directly after FileUpdateHandle() - HANDLE get() const { return hFile; } - -private: - FileUpdateHandle(const FileUpdateHandle&); - FileUpdateHandle& operator=(const FileUpdateHandle&); - - Zstring filenameFmt; - HANDLE hFile; - DWORD attr; -}; -} - -#endif // FILE_UPDATE_HANDLE_H_INCLUDED diff --git a/shared/fixed_list.h b/shared/fixed_list.h deleted file mode 100644 index 97976149..00000000 --- a/shared/fixed_list.h +++ /dev/null @@ -1,142 +0,0 @@ -// ************************************************************************** -// * 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 PTR_WRAP_012384670856841394535 -#define PTR_WRAP_012384670856841394535 - -#include <iterator> - -namespace zen -{ -//std::list(C++11) compatible class supporting inplace element construction for non-copyable/movable types -//may be replaced by C++11 std::list when available -template <class T> -class FixedList -{ - struct Node - { - Node() : next(NULL) {} - template <class A> Node(A && a) : next(NULL), val(a) {} - template <class A, class B> Node(A && a, B && b) : next(NULL), val(a, b) {} - template <class A, class B, class C> Node(A && a, B && b, C && c) : next(NULL), val(a, b, c) {} - template <class A, class B, class C, class D> Node(A && a, B && b, C && c, D && d) : next(NULL), val(a, b, c, d) {} - template <class A, class B, class C, class D, class E> Node(A && a, B && b, C && c, D && d, E && e) : next(NULL), val(a, b, c, d, e) {} - template <class A, class B, class C, class D, class E, class F> Node(A && a, B && b, C && c, D && d, E && e, F && f) : next(NULL), val(a, b, c, d, e, f) {} - - Node* next; //singly linked list is sufficient - T val; - }; - -public: - FixedList() : - first(NULL), - lastInsert(NULL), - sz(0) {} - - ~FixedList() { clear(); } - - template <class NodeT, class U> - class ListIterator : public std::iterator<std::forward_iterator_tag, U> - { - public: - ListIterator(NodeT* it = NULL) : iter(it) {} - ListIterator& operator++() { iter = iter->next; return *this; } - inline friend bool operator==(const ListIterator& lhs, const ListIterator& rhs) { return lhs.iter == rhs.iter; } - inline friend bool operator!=(const ListIterator& lhs, const ListIterator& rhs) { return !(lhs == rhs); } - U& operator* () { return iter->val; } - U* operator->() { return &iter->val; } - private: - NodeT* iter; - }; - - typedef T value_type; - typedef ListIterator<Node, T> iterator; - typedef ListIterator<const Node, const T> const_iterator; - typedef T& reference; - typedef const T& const_reference; - - iterator begin() { return first; } - iterator end() { return iterator(); } - - const_iterator begin() const { return first; } - const_iterator end () const { return const_iterator(); } - - reference front() { return first->val; } - const_reference front() const { return first->val; } - - reference& back() { return lastInsert->val; } - const_reference& back() const { return lastInsert->val; } - - void emplace_back() { pushNode(new Node); } - template <class A> void emplace_back(A && a) { pushNode(new Node(std::forward<A>(a))); } - template <class A, class B> void emplace_back(A && a, B && b) { pushNode(new Node(std::forward<A>(a), std::forward<B>(b))); } - template <class A, class B, class C> void emplace_back(A && a, B && b, C && c) { pushNode(new Node(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c))); } - template <class A, class B, class C, class D> void emplace_back(A && a, B && b, C && c, D && d) { pushNode(new Node(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c), std::forward<D>(d))); } - template <class A, class B, class C, class D, class E> void emplace_back(A && a, B && b, C && c, D && d, E && e) { pushNode(new Node(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c), std::forward<D>(d), std::forward<E>(e))); } - template <class A, class B, class C, class D, class E, class F> void emplace_back(A && a, B && b, C && c, D && d, E && e, F && f) { pushNode(new Node(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c), std::forward<D>(d), std::forward<E>(e), std::forward<F>(f))); } - - template <class Predicate> - void remove_if(Predicate pred) - { - Node* prev = NULL; - for (auto ptr = first; ptr;) - if (pred(ptr->val)) - { - Node* tmp = ptr->next; - deleteNode(ptr); - if (prev) - prev->next = ptr = tmp; - else - first = ptr = tmp; - if (tmp == NULL) - lastInsert = prev; - } - else - { - prev = ptr; - ptr = ptr->next; - } - } - - void clear() { remove_if([](T&) { return true; }); } - bool empty() const { return first == NULL; } - size_t size() const { return sz; } - -private: - FixedList(const FixedList&); - FixedList& operator=(const FixedList&); - - void pushNode(Node* newNode) - { - ++sz; - if (lastInsert == NULL) - { - assert(first == NULL); - first = lastInsert = newNode; - } - else - { - assert(lastInsert->next == NULL); - lastInsert->next = newNode; - lastInsert = newNode; - } - } - - void deleteNode(Node* oldNode) - { - assert(sz > 0); - --sz; - delete oldNode; - } - - Node* first; - Node* lastInsert; //point to last insertion; required by emplace_back() - size_t sz; -}; -} - - -#endif //PTR_WRAP_012384670856841394535 diff --git a/shared/folder_history_box.cpp b/shared/folder_history_box.cpp deleted file mode 100644 index f787e2cb..00000000 --- a/shared/folder_history_box.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// ************************************************************************** -// * 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 "folder_history_box.h" -#include "resolve_path.h" -#include <list> - -using namespace zen; - -FolderHistoryBox::FolderHistoryBox(wxWindow* parent, - wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - int n, - const wxString choices[], - long style, - const wxValidator& validator, - const wxString& name) : - wxComboBox(parent, id, value, pos, size, n, choices, style, validator, name) -#if wxCHECK_VERSION(2, 9, 1) - , dropDownShown(false) -#endif -{ - //##################################### - /*##*/ SetMinSize(wxSize(150, -1)); //## workaround yet another wxWidgets bug: default minimum size is much too large for a wxComboBox - //##################################### - - //register key event to enable item deletion - Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(FolderHistoryBox::OnKeyEvent), NULL, this); - - //refresh history list on mouse click - Connect(wxEVT_LEFT_DOWN, wxEventHandler(FolderHistoryBox::OnUpdateList), NULL, this); - - Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(FolderHistoryBox::OnSelection), NULL, this); - -#if wxCHECK_VERSION(2, 9, 1) - Connect(wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEventHandler(FolderHistoryBox::OnShowDropDown), NULL, this); - Connect(wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEventHandler(FolderHistoryBox::OnHideDropDown), NULL, this); -#endif -} - - -#if wxCHECK_VERSION(2, 9, 1) -void FolderHistoryBox::OnShowDropDown(wxCommandEvent& event) -{ - dropDownShown = true; - event.Skip(); -} - - -void FolderHistoryBox::OnHideDropDown(wxCommandEvent& event) -{ - dropDownShown = false; - event.Skip(); -} -#endif - - -void FolderHistoryBox::update() -{ - std::list<Zstring> dirList; - - //add some aliases to allow user changing to volume name and back, if possible -#ifdef FFS_WIN - const Zstring activePath = toZ(GetValue()); - std::vector<Zstring> aliases = getDirectoryAliases(activePath); - dirList.insert(dirList.end(), aliases.begin(), aliases.end()); -#endif - - if (sharedHistory_.get()) - { - auto tmp = sharedHistory_->getList(); - //std::sort(tmp.begin(), tmp.end(), LessFilename()); - - if (!dirList.empty() && !tmp.empty()) - dirList.push_back(FolderHistory::lineSeparator()); - - dirList.insert(dirList.end(), tmp.begin(), tmp.end()); - } - //########################################################################################### - - - //it may be a little lame to update the list on each mouse-button click, but it should be working and we dont't have to manipulate wxComboBox internals - const wxString oldVal = this->GetValue(); - - Clear(); - std::for_each(dirList.begin(), dirList.end(), - [&](const Zstring& dir) { this->Append(toWx(dir)); }); - - this->SetSelection(wxNOT_FOUND); //don't select anything - this->SetValue(oldVal); //but preserve main text! -} - - -void FolderHistoryBox::OnSelection(wxCommandEvent& event) -{ - event.Skip(); -} - - -void FolderHistoryBox::OnKeyEvent(wxKeyEvent& event) -{ - const int keyCode = event.GetKeyCode(); - if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) - { - //try to delete the currently selected config history item - int pos = this->GetCurrentSelection(); - if (0 <= pos && pos < static_cast<int>(this->GetCount()) && -#if wxCHECK_VERSION(2, 9, 1) - dropDownShown) -#else - //what a mess...: - (GetValue() != GetString(pos) || //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 - const wxString currentVal = this->GetValue(); - //this->SetSelection(wxNOT_FOUND); - - //delete selected row - if (sharedHistory_.get()) - sharedHistory_->delItem(toZ(GetString(pos))); - SetString(pos, wxString()); //in contrast to Delete(), this one does not kill the drop-down list and gives a nice visual feedback! - //Delete(pos); - - //(re-)set value - this->SetValue(currentVal); - - //eat up key event - return; - } - } - event.Skip(); -} diff --git a/shared/folder_history_box.h b/shared/folder_history_box.h deleted file mode 100644 index 3b4fd57e..00000000 --- a/shared/folder_history_box.h +++ /dev/null @@ -1,109 +0,0 @@ -// ************************************************************************** -// * 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 CUSTOMCOMBOBOX_H_INCLUDED -#define CUSTOMCOMBOBOX_H_INCLUDED - -#include <wx/combobox.h> -#include <memory> -#include "zstring.h" -#include "string_conv.h" -#include "stl_tools.h" - -//combobox with history function + functionality to delete items (DEL) -using namespace zen; - - -class FolderHistory -{ -public: - FolderHistory() : maxSize_(0) {} - - FolderHistory(const std::vector<Zstring>& dirnames, size_t maxSize) : - maxSize_(maxSize), - dirnames_(dirnames) - { - if (dirnames_.size() > maxSize_) //keep maximal size of history list - dirnames_.resize(maxSize_); - } - - const std::vector<Zstring>& getList() const { return dirnames_; } - - static const Zstring lineSeparator() { return Zstr("---------------------------------------------------------------------------------------------------------------"); } - - void addItem(const Zstring& dirname) - { - if (dirname.empty() || dirname == lineSeparator()) - return; - - Zstring nameTmp = dirname; - zen::trim(nameTmp); - - //insert new folder or put it to the front if already existing - auto iter = std::find_if(dirnames_.begin(), dirnames_.end(), - [&](const Zstring& entry) { return ::EqualFilename()(entry, nameTmp); }); - - if (iter != dirnames_.end()) - dirnames_.erase(iter); - dirnames_.insert(dirnames_.begin(), nameTmp); - - if (dirnames_.size() > maxSize_) //keep maximal size of history list - dirnames_.resize(maxSize_); - } - - void delItem(const Zstring& dirname) { vector_remove_if(dirnames_, [&](const Zstring& entry) { return ::EqualFilename()(entry, dirname); }); } - -private: - - size_t maxSize_; - std::vector<Zstring> dirnames_; -}; - - -class FolderHistoryBox : public wxComboBox -{ -public: - FolderHistoryBox(wxWindow* parent, - wxWindowID id, - const wxString& value = wxEmptyString, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - int n = 0, - const wxString choices[] = NULL, - long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxComboBoxNameStr); - - void init(const std::shared_ptr<FolderHistory>& sharedHistory) { sharedHistory_ = sharedHistory; } - - void setValue(const wxString& dirname) - { - SetSelection(wxNOT_FOUND); - SetValue(dirname); - update(); //required for Linux to ensure the dropdown is shown as being populated - } - - // GetValue - -private: - void OnKeyEvent(wxKeyEvent& event); - void OnSelection(wxCommandEvent& event); - void OnUpdateList(wxEvent& event) { update(); event.Skip(); } - - void update(); - -#if wxCHECK_VERSION(2, 9, 1) - void OnShowDropDown(wxCommandEvent& event); - void OnHideDropDown(wxCommandEvent& event); - - bool dropDownShown; -#endif - - std::shared_ptr<FolderHistory> sharedHistory_; -}; - - -#endif // CUSTOMCOMBOBOX_H_INCLUDED diff --git a/shared/global_func.h b/shared/global_func.h deleted file mode 100644 index b3c13a24..00000000 --- a/shared/global_func.h +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************** -// * 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 GLOBALFUNCTIONS_H_INCLUDED -#define GLOBALFUNCTIONS_H_INCLUDED - -#include <cmath> - - -namespace common -{ -//little rounding function -inline -int round(double d) { return static_cast<int>(d < 0 ? d - 0.5 : d + 0.5); } - -//absolute value -template <class T> inline -T abs(const T& d) { return d < 0 ? -d : d; } - -inline -size_t getDigitCount(size_t number) { return number == 0 ? 1 : static_cast<size_t>(std::log10(static_cast<double>(number))) + 1; } //count number of digits -} - -#endif //GLOBALFUNCTIONS_H_INCLUDED diff --git a/shared/guid.cpp b/shared/guid.cpp deleted file mode 100644 index 1cc304cb..00000000 --- a/shared/guid.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// ************************************************************************** -// * 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 "guid.h" -#include <boost/uuid/uuid.hpp> - -//boost really should clean a bit up... -#ifdef __MINGW32__ -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif - -#include <boost/uuid/uuid_generators.hpp> - - -std::string util::generateGUID() //creates a 16 byte GUID -{ - boost::uuids::uuid nativeRep = boost::uuids::random_generator()(); - return std::string(nativeRep.begin(), nativeRep.end()); -} - diff --git a/shared/guid.h b/shared/guid.h deleted file mode 100644 index 1986b101..00000000 --- a/shared/guid.h +++ /dev/null @@ -1,19 +0,0 @@ -// ************************************************************************** -// * 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 GUID_H_INCLUDED -#define GUID_H_INCLUDED - -#include <string> - - -namespace util -{ -std::string generateGUID(); //creates a 16 byte GUID -} - - -#endif // GUID_H_INCLUDED diff --git a/shared/help_provider.cpp b/shared/help_provider.cpp deleted file mode 100644 index 666482eb..00000000 --- a/shared/help_provider.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************** -// * 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 "help_provider.h" -#include <wx/help.h> -#include "standard_paths.h" -#include <wx/image.h> - -namespace -{ -class HelpProvider -{ -public: - HelpProvider() - { - controller.Initialize(zen::getResourceDir() + -#ifdef FFS_WIN - L"FreeFileSync.chm"); -#elif defined FFS_LINUX - L"Help/FreeFileSync.hhp"); -#endif - } - - void showHelp(const wxString& section) - { - if (section.empty()) - controller.DisplayContents(); - else - controller.DisplaySection(section); - } - -private: - wxHelpController controller; -}; -} - -void zen::displayHelpEntry(const wxString& section) -{ - static HelpProvider provider; - provider.showHelp(section); -} diff --git a/shared/help_provider.h b/shared/help_provider.h deleted file mode 100644 index dbe3ce26..00000000 --- a/shared/help_provider.h +++ /dev/null @@ -1,17 +0,0 @@ -// ************************************************************************** -// * 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 HELPPROVIDER_H_INCLUDED -#define HELPPROVIDER_H_INCLUDED - -#include <wx/string.h> - -namespace zen -{ -void displayHelpEntry(const wxString& section = wxEmptyString); -} - -#endif // HELPPROVIDER_H_INCLUDED diff --git a/shared/i18n.cpp b/shared/i18n.cpp deleted file mode 100644 index a5fb32dd..00000000 --- a/shared/i18n.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "i18n.h" -#include <memory> - -using namespace zen; - - -namespace -{ -std::unique_ptr<TranslationHandler> globalHandler; -} - -void zen::setTranslator(TranslationHandler* newHandler) -{ - globalHandler.reset(newHandler); -} - - -TranslationHandler* zen::getTranslator() -{ - return globalHandler.get(); -} diff --git a/shared/i18n.h b/shared/i18n.h deleted file mode 100644 index 8aa38f3c..00000000 --- a/shared/i18n.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************** -// * 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 I18_N_HEADER_3843489325045 -#define I18_N_HEADER_3843489325045 - -#include <string> - -namespace zen -{ -//implement handler to enable program wide localizations -struct TranslationHandler -{ - virtual ~TranslationHandler() {} - - virtual std::wstring thousandsSeparator() = 0; - virtual std::wstring translate(const std::wstring& text) = 0; //simple translation - virtual std::wstring translate(const std::wstring& singular, const std::wstring& plural, int n) = 0; -}; - -void setTranslator(TranslationHandler* newHandler = NULL); //takes ownership -TranslationHandler* getTranslator(); - - - -inline std::wstring getThousandsSeparator() { return getTranslator() ? getTranslator()->thousandsSeparator() : L","; }; - -inline std::wstring translate(const std::wstring& text) { return getTranslator() ? getTranslator()->translate(text) : text; } - -//translate plural forms: "%x day" "%x days" -//returns "%x day" if n == 1; "%x days" else for english language -inline std::wstring translate(const std::wstring& singular, const std::wstring& plural, int n) { return getTranslator() ? getTranslator()->translate(singular, plural, n) : n == 1 ? singular : plural; } - -template <class T> inline -std::wstring translate(const std::wstring& singular, const std::wstring& plural, T n) -{ - return translate(singular, plural, static_cast<int>(n % 1000000)); -} -} - -#define CONCAT_HELPER(txt1, txt2) txt1 ## txt2 - -#ifndef WXINTL_NO_GETTEXT_MACRO -#error WXINTL_NO_GETTEXT_MACRO must be defined to deactivate wxWidgets underscore macro -#endif - -#define _(s) zen::translate(CONCAT_HELPER(L, s)) -#define _P(s, p, n) zen::translate(CONCAT_HELPER(L, s), CONCAT_HELPER(L, p), n) - -#endif //I18_N_HEADER_3843489325045 diff --git a/shared/image_tools.h b/shared/image_tools.h deleted file mode 100644 index e78e7ced..00000000 --- a/shared/image_tools.h +++ /dev/null @@ -1,157 +0,0 @@ -// ************************************************************************** -// * 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 IMAGE_TOOLS_HEADER_45782456427634254 -#define IMAGE_TOOLS_HEADER_45782456427634254 - -#include <numeric> -#include <wx/bitmap.h> -#include <wx/dcmemory.h> - - -namespace zen -{ -wxBitmap greyScale(const wxBitmap& bmp); //greyscale + brightness adaption -wxBitmap layOver(const wxBitmap& foreground, const wxBitmap& background); //merge - -void move(wxImage& img, int up, int left = 0); -void adjustBrightness(wxImage& img, int targetLevel); -double getAvgBrightness(const wxImage& img); //in [0, 255] -void brighten(wxImage& img, int level); //level: delta per channel in points - -bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs); //pixel-wise equality (respecting alpha channel) - - - - - - - - - - - - - - - - - -//################################### implementation ################################### -inline -void move(wxImage& img, int up, int left) -{ - img = img.GetSubImage(wxRect(std::max(0, left), std::max(0, up), img.GetWidth() - abs(left), img.GetHeight() - abs(up))); - img.Resize(wxSize(img.GetWidth() + abs(left), img.GetHeight() + abs(up)), wxPoint(-std::min(0, left), -std::min(0, up))); -} - - -inline -wxBitmap greyScale(const wxBitmap& bmp) -{ - wxImage output = bmp.ConvertToImage().ConvertToGreyscale(1.0/3, 1.0/3, 1.0/3); //treat all channels equally! - //wxImage output = bmp.ConvertToImage().ConvertToGreyscale(); - adjustBrightness(output, 170); - return output; -} - - -inline -double getAvgBrightness(const wxImage& img) -{ - const int pixelCount = img.GetWidth() * img.GetHeight(); - auto pixBegin = img.GetData(); - if (pixBegin) - { - auto pixEnd = pixBegin + 3 * pixelCount; //RGB - - if (img.HasAlpha()) - { - const unsigned char* alphaFirst = img.GetAlpha(); - - //calculate average weighted by alpha channel - double dividend = 0; - for (auto iter = pixBegin; iter != pixEnd; ++iter) - dividend += *iter * static_cast<double>(alphaFirst[(iter - pixBegin) / 3]); - - const int divisor = 3.0 * std::accumulate(alphaFirst, alphaFirst + pixelCount, 0.0); - - return dividend / divisor; - } - else - return std::accumulate(pixBegin, pixEnd, 0.0) / (3.0 * pixelCount); - } - return 0; -} - - -inline -void brighten(wxImage& img, int level) -{ - const int pixelCount = img.GetWidth() * img.GetHeight(); - auto pixBegin = img.GetData(); - if (pixBegin) - { - auto pixEnd = pixBegin + 3 * pixelCount; //RGB - if (level > 0) - std::for_each(pixBegin, pixEnd, [&](unsigned char& c) { c = std::min(255, c + level); }); - else - std::for_each(pixBegin, pixEnd, [&](unsigned char& c) { c = std::max(0, c + level); }); - } -} - - -inline -void adjustBrightness(wxImage& img, int targetLevel) -{ - brighten(img, targetLevel - getAvgBrightness(img)); -} - - -inline -wxBitmap layOver(const wxBitmap& foreground, const wxBitmap& background) -{ - wxBitmap output = background; - { - wxMemoryDC dc; - dc.SelectObject(output); - dc.DrawBitmap(foreground, 0, 0, true); - dc.SelectObject(wxNullBitmap); - } - return output; -} - - -inline -bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs) -{ - if (lhs.IsOk() != rhs.IsOk()) - return false; - if (!lhs.IsOk()) - return true; - - const int pixelCount = lhs.GetWidth() * lhs.GetHeight(); - if (pixelCount != rhs.GetWidth() * rhs.GetHeight()) - return false; - - wxImage imLhs = lhs.ConvertToImage(); - wxImage imRhs = rhs.ConvertToImage(); - - if (imLhs.HasAlpha() != imRhs.HasAlpha()) - return false; - - if (imLhs.HasAlpha()) - { - if (!std::equal(imLhs.GetAlpha(), imLhs.GetAlpha() + pixelCount, imRhs.GetAlpha())) - return false; - } - - return std::equal(imLhs.GetData(), imLhs.GetData() + pixelCount * 3, imRhs.GetData()); -} -} - - -#endif //IMAGE_TOOLS_HEADER_45782456427634254 diff --git a/shared/int64.h b/shared/int64.h deleted file mode 100644 index cfd3e3d1..00000000 --- a/shared/int64.h +++ /dev/null @@ -1,248 +0,0 @@ -// ************************************************************************** -// * 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 FFS_LARGE_64_BIT_INTEGER_H_INCLUDED -#define FFS_LARGE_64_BIT_INTEGER_H_INCLUDED - -#include <cassert> -#include <ostream> -#include <limits> -#include <boost/cstdint.hpp> -#include <boost/numeric/conversion/bounds.hpp> -#include "assert_static.h" -#include "loki/TypeManip.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> -#endif - - -/* -zen::Int64/zen::UInt64: wrapper classes around boost::int64_t/boost::uint64_t - - - default initialization with 0 - - debug runtime overflow/underflow checks - - safe and explicit semantics: no unsafe type conversions - - safe conversion to and from Windows 64-bit integers - - specializes std::numeric_limits - - support stream operator<< and operator>> -*/ - -namespace zen -{ -template <class T, class U> inline void checkRange(U value) -{ - //caveat: std::numeric_limits<T>::min returns minimum positive(!) number for T = double, while behaving correctly for integer types... sigh - //std::numeric_limits<T>::lowest() not available before C++11 - assert(double(boost::numeric::bounds<T>::lowest ()) <= double(value) && - double(boost::numeric::bounds<T>::highest()) >= double(value)); -} - -class Int64 -{ - struct DummyClass { operator int() { return 0; } }; -public: - //safe implicit conversions - Int64() : value(0) {} - Int64(const Int64& rhs) : value(rhs.value) {} - Int64(int rhs) : value(rhs) {} //ambiguity intentional for types other than these - Int64(long rhs) : value(rhs) {} - Int64(Loki::Select<Loki::IsSameType<boost::int64_t, long>::value, DummyClass, boost::int64_t>::Result rhs) : - value(rhs) {} //-> boost::int64_t equals long int on x64 Linux! Still we want implicit behavior for all other systems! - - //unsafe explicit but checked conversion from arbitrary integer type - template <class T> explicit Int64(T rhs) : value(rhs) { checkRange<boost::int64_t>(rhs); } - - Int64& operator=(const Int64& rhs) { value = rhs.value; return *this; } - -#ifdef FFS_WIN - Int64(DWORD low, LONG high) - { - assert_static(sizeof(low) + sizeof(high) == sizeof(value)); - - LARGE_INTEGER cvt = {}; - cvt.LowPart = low; - cvt.HighPart = high; - value = cvt.QuadPart; - } - LONG getHi() const - { - LARGE_INTEGER cvt = {}; - cvt.QuadPart = value; - return cvt.HighPart; - } - DWORD getLo() const - { - LARGE_INTEGER cvt = {}; - cvt.QuadPart = value; - return cvt.LowPart; - } -#endif - - Int64& operator+=(const Int64& rhs) { checkRange<boost::int64_t>(double(value) + rhs.value); value += rhs.value; return *this; } - Int64& operator-=(const Int64& rhs) { checkRange<boost::int64_t>(double(value) - rhs.value); value -= rhs.value; return *this; } - Int64& operator*=(const Int64& rhs) { checkRange<boost::int64_t>(double(value) * rhs.value); value *= rhs.value; return *this; } - Int64& operator/=(const Int64& rhs) { assert(rhs.value != 0); value /= rhs.value; return *this; } - Int64& operator%=(const Int64& rhs) { assert(rhs.value != 0); value %= rhs.value; return *this; } - Int64& operator&=(const Int64& rhs) { value &= rhs.value; return *this;} - Int64& operator|=(const Int64& rhs) { value |= rhs.value; return *this;} - Int64& operator<<=(int rhs) { assert(rhs < 0 || (value << rhs) >> rhs == value); value <<= rhs; return *this; } - Int64& operator>>=(int rhs) { assert(rhs > 0 || (value >> rhs) << rhs == value); value >>= rhs; return *this; } - - inline friend bool operator==(const Int64& lhs, const Int64& rhs) { return lhs.value == rhs.value; } - inline friend bool operator!=(const Int64& lhs, const Int64& rhs) { return lhs.value != rhs.value; } - inline friend bool operator< (const Int64& lhs, const Int64& rhs) { return lhs.value < rhs.value; } - inline friend bool operator> (const Int64& lhs, const Int64& rhs) { return lhs.value > rhs.value; } - inline friend bool operator<=(const Int64& lhs, const Int64& rhs) { return lhs.value <= rhs.value; } - inline friend bool operator>=(const Int64& lhs, const Int64& rhs) { return lhs.value >= rhs.value; } - - //checked conversion to arbitrary target integer type - template <class T> inline friend T to(Int64 number) { checkRange<T>(number.value); return static_cast<T>(number.value); } - - template <class T> inline friend std::basic_istream<T>& operator>>(std::basic_istream<T>& lhs, Int64& rhs) { lhs >> rhs.value; return lhs; } - template <class T> inline friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, const Int64& rhs) { lhs << rhs.value; return lhs; } - -private: - boost::int64_t value; -}; - -inline Int64 operator+(const Int64& lhs, const Int64& rhs) { return Int64(lhs) += rhs; } -inline Int64 operator-(const Int64& lhs, const Int64& rhs) { return Int64(lhs) -= rhs; } -inline Int64 operator*(const Int64& lhs, const Int64& rhs) { return Int64(lhs) *= rhs; } -inline Int64 operator/(const Int64& lhs, const Int64& rhs) { return Int64(lhs) /= rhs; } -inline Int64 operator%(const Int64& lhs, const Int64& rhs) { return Int64(lhs) %= rhs; } -inline Int64 operator&(const Int64& lhs, const Int64& rhs) { return Int64(lhs) &= rhs; } -inline Int64 operator|(const Int64& lhs, const Int64& rhs) { return Int64(lhs) |= rhs; } -inline Int64 operator<<(const Int64& lhs, int rhs) { return Int64(lhs) <<= rhs; } -inline Int64 operator>>(const Int64& lhs, int rhs) { return Int64(lhs) >>= rhs; } - - -class UInt64 -{ - struct DummyClass { operator size_t() { return 0U; } }; -public: - //safe implicit conversions - UInt64() : value(0) {} - UInt64(const UInt64& rhs) : value(rhs.value) {} - UInt64(unsigned int rhs) : value(rhs) {} //ambiguity intentional for types other than these - UInt64(unsigned long rhs) : value(rhs) {} - UInt64(Loki::Select<Loki::IsSameType<boost::uint64_t, unsigned long>::value, DummyClass, boost::uint64_t>::Result rhs) : - value(rhs) {} //-> boost::uint64_t equals unsigned long int on x64 Linux! Still we want implicit behavior for all other systems! - - //unsafe explicit but checked conversion from arbitrary integer type - template <class T> explicit UInt64(T rhs) : value(rhs) { checkRange<boost::uint64_t>(rhs); } - - UInt64& operator=(const UInt64& rhs) { value = rhs.value; return *this; } - -#ifdef FFS_WIN - UInt64(DWORD low, DWORD high) - { - assert_static(sizeof(low) + sizeof(high) == sizeof(value)); - - ULARGE_INTEGER cvt = {}; - cvt.LowPart = low; - cvt.HighPart = high; - value = cvt.QuadPart; - } - DWORD getHi() const - { - ULARGE_INTEGER cvt = {}; - cvt.QuadPart = value; - return cvt.HighPart; - } - DWORD getLo() const - { - ULARGE_INTEGER cvt = {}; - cvt.QuadPart = value; - return cvt.LowPart; - } -#endif - - UInt64& operator+=(const UInt64& rhs) { checkRange<boost::uint64_t>(double(value) + rhs.value); value += rhs.value; return *this; } - UInt64& operator-=(const UInt64& rhs) { checkRange<boost::uint64_t>(double(value) - rhs.value); value -= rhs.value; return *this; } - UInt64& operator*=(const UInt64& rhs) { checkRange<boost::uint64_t>(double(value) * rhs.value); value *= rhs.value; return *this; } - UInt64& operator/=(const UInt64& rhs) { assert(rhs.value != 0); value /= rhs.value; return *this; } - UInt64& operator%=(const UInt64& rhs) { assert(rhs.value != 0); value %= rhs.value; return *this; } - UInt64& operator&=(const UInt64& rhs) { value &= rhs.value; return *this;} - UInt64& operator|=(const UInt64& rhs) { value |= rhs.value; return *this;} - UInt64& operator<<=(int rhs) { assert(rhs < 0 || (value << rhs) >> rhs == value); value <<= rhs; return *this; } - UInt64& operator>>=(int rhs) { assert(rhs > 0 || (value >> rhs) << rhs == value); value >>= rhs; return *this; } - - inline friend bool operator==(const UInt64& lhs, const UInt64& rhs) { return lhs.value == rhs.value; } - inline friend bool operator!=(const UInt64& lhs, const UInt64& rhs) { return lhs.value != rhs.value; } - inline friend bool operator< (const UInt64& lhs, const UInt64& rhs) { return lhs.value < rhs.value; } - inline friend bool operator> (const UInt64& lhs, const UInt64& rhs) { return lhs.value > rhs.value; } - inline friend bool operator<=(const UInt64& lhs, const UInt64& rhs) { return lhs.value <= rhs.value; } - inline friend bool operator>=(const UInt64& lhs, const UInt64& rhs) { return lhs.value >= rhs.value; } - - //checked conversion to arbitrary target integer type - template <class T> inline friend T to(UInt64 number) { checkRange<T>(number.value); return static_cast<T>(number.value); } - - template <class T> inline friend std::basic_istream<T>& operator>>(std::basic_istream<T>& lhs, UInt64& rhs) { lhs >> rhs.value; return lhs; } - template <class T> inline friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, const UInt64& rhs) { lhs << rhs.value; return lhs; } - -private: - boost::uint64_t value; -}; - -inline UInt64 operator+(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) += rhs; } -inline UInt64 operator-(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) -= rhs; } -inline UInt64 operator*(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) *= rhs; } -inline UInt64 operator/(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) /= rhs; } -inline UInt64 operator%(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) %= rhs; } -inline UInt64 operator&(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) &= rhs; } -inline UInt64 operator|(const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) |= rhs; } -inline UInt64 operator<<(const UInt64& lhs, int rhs) { return UInt64(lhs) <<= rhs; } -inline UInt64 operator>>(const UInt64& lhs, int rhs) { return UInt64(lhs) >>= rhs; } - -template <> inline UInt64 to(Int64 number) { checkRange<boost::uint64_t>(number.value); return UInt64(number.value); } -template <> inline Int64 to(UInt64 number) { checkRange<boost:: int64_t>(number.value); return Int64(number.value); } - - -#ifdef FFS_WIN -//convert FILETIME (number of 100-nanosecond intervals since January 1, 1601 UTC) -// to time_t (number of seconds since Jan. 1st 1970 UTC) -// -//FAT32 time is preserved exactly: FAT32 -> toTimeT -> tofiletime -> FAT32 -inline -Int64 toTimeT(const FILETIME& ft) -{ - return to<Int64>(UInt64(ft.dwLowDateTime, ft.dwHighDateTime) / 10000000U) - Int64(3054539008UL, 2); - //timeshift between ansi C time and FILETIME in seconds == 11644473600s -} - -inline -FILETIME tofiletime(const Int64& utcTime) -{ - const UInt64 fileTimeLong = to<UInt64>(utcTime + Int64(3054539008UL, 2)) * 10000000U; - const FILETIME output = { fileTimeLong.getLo(), fileTimeLong.getHi() }; - return output; -} -#endif -} - - -namespace std -{ -assert_static(std::numeric_limits<boost:: int64_t>::is_specialized); -assert_static(std::numeric_limits<boost::uint64_t>::is_specialized); - -template <> class numeric_limits<zen::Int64> : public numeric_limits<boost::int64_t> -{ -public: - static zen::Int64 min() throw() { return numeric_limits<boost::int64_t>::min(); } - static zen::Int64 max() throw() { return numeric_limits<boost::int64_t>::max(); } -}; - -template <> class numeric_limits<zen::UInt64> : public numeric_limits<boost::uint64_t> -{ -public: - static zen::UInt64 min() throw() { return numeric_limits<boost::uint64_t>::min(); } - static zen::UInt64 max() throw() { return numeric_limits<boost::uint64_t>::max(); } -}; -} - -#endif //FFS_LARGE_64_BIT_INTEGER_H_INCLUDED diff --git a/shared/last_error.cpp b/shared/last_error.cpp deleted file mode 100644 index 57053c30..00000000 --- a/shared/last_error.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************** -// * 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 "last_error.h" -#include "string_utf8.h" -#include "i18n.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" - -#elif defined FFS_LINUX -#include <cstring> -#include <cerrno> -#endif - -using namespace zen; - - -#ifdef FFS_WIN -std::wstring zen::getLastErrorFormatted(unsigned long lastError) //try to get additional Windows error information -{ - //determine error code if none was specified - if (lastError == 0) - lastError = ::GetLastError(); - - std::wstring output = _("Windows Error Code %x:"); - replace(output, L"%x", toString<std::wstring>(lastError)); - - LPWSTR buffer = NULL; - if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_MAX_WIDTH_MASK | - FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastError, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0) - { - if (buffer) //just to be sure - { - output += L" "; - output += buffer; - ::LocalFree(buffer); - } - } - ::SetLastError(lastError); //restore last error - return output; -} - -#elif defined FFS_LINUX -std::wstring zen::getLastErrorFormatted(int lastError) //try to get additional Linux error information -{ - //determine error code if none was specified - if (lastError == 0) - lastError = errno; //don't use "::", errno is a macro! - - std::wstring output = _("Linux Error Code %x:"); - replace(output, L"%x", toString<std::wstring>(lastError)); - - output += L" "; - output += utf8CvrtTo<std::wstring>(::strerror(lastError)); - - errno = lastError; //restore errno - return output; -} -#endif diff --git a/shared/last_error.h b/shared/last_error.h deleted file mode 100644 index 3e90a1a0..00000000 --- a/shared/last_error.h +++ /dev/null @@ -1,24 +0,0 @@ -// ************************************************************************** -// * 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 SYSTEMFUNCTIONS_H_INCLUDED -#define SYSTEMFUNCTIONS_H_INCLUDED - -#include <string> - - -namespace zen -{ -//evaluate GetLastError()/errno and assemble specific error message -#ifdef FFS_WIN -std::wstring getLastErrorFormatted(unsigned long lastError = 0); -#elif defined FFS_LINUX -std::wstring getLastErrorFormatted(int lastError = 0); -#endif -} - - -#endif // SYSTEMFUNCTIONS_H_INCLUDED diff --git a/shared/localization.cpp b/shared/localization.cpp deleted file mode 100644 index 73aa5b72..00000000 --- a/shared/localization.cpp +++ /dev/null @@ -1,435 +0,0 @@ -// ************************************************************************** -// * 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 "localization.h" -#include <fstream> -#include <map> -#include <list> -#include <iterator> -#include <wx/ffile.h> -#include <wx/intl.h> -#include <wx/msgdlg.h> -#include "parse_plural.h" -#include "parse_lng.h" -#include "util.h" -#include "string_tools.h" -#include "file_traverser.h" -#include "standard_paths.h" -#include "string_conv.h" -#include "zenXml/zenxml_io.h" -#include "i18n.h" - -using namespace zen; - - -namespace -{ -//global objects -std::wstring THOUSANDS_SEPARATOR = L","; - - -class FFSLocale : public TranslationHandler -{ -public: - FFSLocale(const wxString& filename, wxLanguage languageId); //throw (lngfile::ParsingError, PluralForm::ParsingError) - - wxLanguage langId() const { return langId_; } - - virtual std::wstring thousandsSeparator() { return THOUSANDS_SEPARATOR; }; - - virtual std::wstring translate(const std::wstring& text) - { - //look for translation in buffer table - const Translation::const_iterator iter = transMapping.find(text); - if (iter != transMapping.end()) - return iter->second; - - return text; //fallback - } - - virtual std::wstring translate(const std::wstring& singular, const std::wstring& plural, int n) - { - TranslationPlural::const_iterator iter = transMappingPl.find(std::make_pair(singular, plural)); - if (iter != transMappingPl.end()) - { - const int formNo = pluralParser->getForm(n); - if (0 <= formNo && formNo < static_cast<int>(iter->second.size())) - return iter->second[formNo]; - } - - return n == 1 ? singular : plural; //fallback - } - -private: - typedef std::map<std::wstring, std::wstring> Translation; - typedef std::map<std::pair<std::wstring, std::wstring>, std::vector<std::wstring> > TranslationPlural; - - Translation transMapping; //map original text |-> translation - TranslationPlural transMappingPl; - std::unique_ptr<PluralForm> pluralParser; - wxLanguage langId_; -}; - - - -FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_(languageId) //throw (lngfile::ParsingError, PluralForm::ParsingError) -{ - std::string inputStream; - try - { - inputStream = loadStream(filename);; //throw XmlFileError - } - catch (...) - { - throw lngfile::ParsingError(0, 0); - } - - lngfile::TransHeader header; - lngfile::TranslationMap transInput; - lngfile::TranslationPluralMap transPluralInput; - lngfile::parseLng(inputStream, header, transInput, transPluralInput); //throw ParsingError - - for (lngfile::TranslationMap::const_iterator i = transInput.begin(); i != transInput.end(); ++i) - { - const std::wstring original = utf8CvrtTo<std::wstring>(i->first); - const std::wstring translation = utf8CvrtTo<std::wstring>(i->second); - assert(!translation.empty()); - transMapping.insert(std::make_pair(original , translation)); - } - - for (lngfile::TranslationPluralMap::const_iterator i = transPluralInput.begin(); i != transPluralInput.end(); ++i) - { - const std::wstring singular = utf8CvrtTo<std::wstring>(i->first.first); - const std::wstring plural = utf8CvrtTo<std::wstring>(i->first.second); - const lngfile::PluralForms& plForms = i->second; - - std::vector<std::wstring> plFormsWide; - for (lngfile::PluralForms::const_iterator j = plForms.begin(); j != plForms.end(); ++j) - plFormsWide.push_back(utf8CvrtTo<std::wstring>(*j)); - - assert(!plFormsWide.empty()); - - transMappingPl.insert(std::make_pair(std::make_pair(singular, plural), plFormsWide)); - } - - pluralParser.reset(new PluralForm(header.pluralDefinition.c_str())); //throw PluralForm::ParsingError -} -} - - -class FindLngfiles : public zen::TraverseCallback -{ -public: - FindLngfiles(std::vector<Zstring>& lngFiles) : lngFiles_(lngFiles) {} - - virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) - { - if (endsWith(fullName, Zstr(".lng"))) - lngFiles_.push_back(fullName); - } - - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} - virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) { return Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); } - virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context - -private: - std::vector<Zstring>& lngFiles_; -}; - - -struct LessTranslation : public std::binary_function<ExistingTranslations::Entry, ExistingTranslations::Entry, bool> -{ - bool operator()(const ExistingTranslations::Entry& lhs, const ExistingTranslations::Entry& rhs) const - { -#ifdef FFS_WIN - //use a more "natural" sort, that is ignore case and diacritics - const int rv = ::CompareString(LOCALE_USER_DEFAULT, //__in LCID Locale, - NORM_IGNORECASE, //__in DWORD dwCmpFlags, - lhs.languageName.c_str(), //__in LPCTSTR lpString1, - static_cast<int>(lhs.languageName.size()), //__in int cchCount1, - rhs.languageName.c_str(), //__in LPCTSTR lpString2, - static_cast<int>(rhs.languageName.size())); //__in int cchCount2 - if (rv == 0) - throw std::runtime_error("Error comparing strings!"); - else - return rv == CSTR_LESS_THAN; //convert to C-style string compare result -#else - return lhs.languageName < rhs.languageName; -#endif - } -}; - - -ExistingTranslations::ExistingTranslations() -{ - { - //default entry: - ExistingTranslations::Entry newEntry; - newEntry.languageID = wxLANGUAGE_ENGLISH_US; - newEntry.languageName = wxT("English (US)"); - newEntry.languageFile = wxT(""); - newEntry.translatorName = wxT("ZenJu"); - newEntry.languageFlag = wxT("usa.png"); - locMapping.push_back(newEntry); - } - - //search language files available - std::vector<Zstring> lngFiles; - FindLngfiles traverseCallback(lngFiles); - - traverseFolder(toZ(zen::getResourceDir() + wxT("Languages")), //throw(); - false, //don't follow symlinks - traverseCallback); - - for (auto i = lngFiles.begin(); i != lngFiles.end(); ++i) - { - try - { - std::string stream = loadStream(*i);; //throw XmlFileError - try - { - lngfile::TransHeader lngHeader; - lngfile::parseHeader(stream, lngHeader); //throw ParsingError - - const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName)); - if (locInfo) - { - ExistingTranslations::Entry newEntry; - newEntry.languageID = locInfo->Language; - newEntry.languageName = utf8CvrtTo<wxString>(lngHeader.languageName); - newEntry.languageFile = toWx(*i); - newEntry.translatorName = utf8CvrtTo<wxString>(lngHeader.translatorName); - newEntry.languageFlag = utf8CvrtTo<wxString>(lngHeader.flagFile); - locMapping.push_back(newEntry); - } - } - catch (lngfile::ParsingError&) {} - } - catch (...) {} - } - - std::sort(locMapping.begin(), locMapping.end(), LessTranslation()); -} - - -namespace -{ -wxLanguage mapLanguageDialect(wxLanguage language) -{ - switch (static_cast<int>(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_DANISH: - //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: - //case wxLANGUAGE_UKRAINIAN: - - //variants of wxLANGUAGE_ARABIC - 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; - } -} -} - - -class CustomLocale -{ -public: - CustomLocale(int selectedLng) - { - const wxLanguageInfo* sysLngInfo = wxLocale::GetLanguageInfo(wxLocale::GetSystemLanguage()); - const wxLanguageInfo* selLngInfo = wxLocale::GetLanguageInfo(selectedLng); - - bool sysLangIsRTL = sysLngInfo ? sysLngInfo->LayoutDirection == wxLayout_RightToLeft : false; - bool selectedLangIsRTL = selLngInfo ? selLngInfo->LayoutDirection == wxLayout_RightToLeft : false; - - if (sysLangIsRTL == selectedLangIsRTL) - loc.Init(wxLANGUAGE_DEFAULT); //use sys-lang to preserve sub-language specific rules (e.g. german swiss number punctation) - else - loc.Init(selectedLng); - - //::setlocale (LC_ALL, ""); -> implicitly called by wxLocale - const lconv* localInfo = ::localeconv(); - - //actually these two parameters are language dependent, but we take system setting to handle all kinds of language derivations - THOUSANDS_SEPARATOR = utf8CvrtTo<wxString>(localInfo->thousands_sep); - - // 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(); - } -private: - wxLocale loc; //required for RTL language support (and nothing else) -}; - - -void zen::setLanguage(int language) -{ - //(try to) retrieve language file - wxString languageFile; - for (std::vector<ExistingTranslations::Entry>::const_iterator i = ExistingTranslations::get().begin(); i != ExistingTranslations::get().end(); ++i) - if (i->languageID == language) - { - languageFile = i->languageFile; - break; - } - - - //handle RTL swapping: we need wxWidgets to do this - static std::unique_ptr<CustomLocale> dummy; - dummy.reset(); //avoid global locale lifetime overlap! wxWidgets cannot handle this and will crash! - dummy.reset(new CustomLocale(languageFile.empty() ? wxLANGUAGE_ENGLISH : language)); - - - //reset to english language; in case of error show error message just once - zen::setTranslator(); - - //load language file into buffer - if (!languageFile.empty()) //if languageFile is empty texts will be english per default - { - try - { - zen::setTranslator(new FFSLocale(languageFile, static_cast<wxLanguage>(language))); //throw (lngfile::ParsingError, PluralForm::ParsingError) - } - catch (lngfile::ParsingError& e) - { - wxMessageBox(wxString(_("Error reading file:")) + wxT(" \"") + languageFile + wxT("\"") + wxT("\n\n") + - wxT("Row: ") + zen::toStringSep(e.row) + wxT("\n") + - wxT("Column: ") + zen::toStringSep(e.col) + wxT("\n"), _("Error"), wxOK | wxICON_ERROR); - } - catch (PluralForm::ParsingError&) - { - wxMessageBox(wxT("Invalid Plural Form"), _("Error"), wxOK | wxICON_ERROR); - } - } -} - - - -int zen::getLanguage() -{ - FFSLocale* loc = dynamic_cast<FFSLocale*>(zen::getTranslator()); - return loc ? loc->langId() : wxLANGUAGE_ENGLISH_US; -} - - -int zen::retrieveSystemLanguage() -{ - return mapLanguageDialect(static_cast<wxLanguage>(wxLocale::GetSystemLanguage())); -} - - -const std::vector<ExistingTranslations::Entry>& ExistingTranslations::get() -{ - static ExistingTranslations instance; - return instance.locMapping; -} diff --git a/shared/localization.h b/shared/localization.h deleted file mode 100644 index 438ad445..00000000 --- a/shared/localization.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************** -// * 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 MISC_H_INCLUDED -#define MISC_H_INCLUDED - -#include <wx/string.h> -#include <vector> - -namespace zen -{ -class ExistingTranslations -{ -public: - struct Entry - { - int languageID; - wxString languageName; - wxString languageFile; - wxString translatorName; - wxString languageFlag; - }; - static const std::vector<Entry>& get(); - -private: - ExistingTranslations(); - ExistingTranslations(const ExistingTranslations&); - ExistingTranslations& operator=(const ExistingTranslations&); - - std::vector<Entry> locMapping; -}; - -void setLanguage(int language); -int getLanguage(); -int retrieveSystemLanguage(); -} - -#endif // MISC_H_INCLUDED diff --git a/shared/loki/AbstractFactory.h b/shared/loki/AbstractFactory.h deleted file mode 100644 index 615652bd..00000000 --- a/shared/loki/AbstractFactory.h +++ /dev/null @@ -1,185 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_ABSTRACTFACTORY_INC_ -#define LOKI_ABSTRACTFACTORY_INC_ - -// $Id: AbstractFactory.h 771 2006-10-27 18:05:03Z clitte_bbt $ - - -#include "Typelist.h" -#include "Sequence.h" -#include "TypeManip.h" -#include "HierarchyGenerators.h" - -#include <cassert> - -/** - * \defgroup FactoriesGroup Factories - * \defgroup AbstractFactoryGroup Abstract Factory - * \ingroup FactoriesGroup - * \brief Implements an abstract object factory. - */ - -/** - * \class AbstractFactory - * \ingroup AbstractFactoryGroup - * \brief Implements an abstract object factory. - */ - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -// class template AbstractFactoryUnit -// The building block of an Abstract Factory -//////////////////////////////////////////////////////////////////////////////// - -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> -{ -public: - typedef TList ProductList; - - template <class T> T* Create() - { - 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 -{ - typedef typename Base::ProductList BaseProductList; - -protected: - typedef typename BaseProductList::Tail ProductList; - -public: - typedef typename BaseProductList::Head AbstractProduct; - ConcreteProduct* DoCreate(Type2Type<AbstractProduct>) - { - 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 -// 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 -{ - 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; } - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -} // namespace Loki - - -#endif // end file guardian - diff --git a/shared/loki/Allocator.h b/shared/loki/Allocator.h deleted file mode 100644 index 39b63912..00000000 --- a/shared/loki/Allocator.h +++ /dev/null @@ -1,153 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// - -#ifndef LOKI_ALLOCATOR_HPP_INCLUDED -#define LOKI_ALLOCATOR_HPP_INCLUDED - -// $Id: Allocator.h 896 2008-08-08 22:20:05Z syntheticpp $ - -// Requires project to be compiled with loki/src/SmallObj.cpp and loki/src/Singleton.cpp - -#include <loki/SmallObj.h> - - -namespace Loki -{ - - -//----------------------------------------------------------------------------- - -/** @class LokiAllocator - Adapts Loki's Small-Object Allocator for STL container classes. - This class provides all the functionality required for STL allocators, but - uses Loki's Small-Object Allocator to perform actual memory operations. - Implementation comes from a post in Loki forums (by Rasmus Ekman?). - */ -template -< -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 value_type; - - /// Default constructor does nothing. - inline LokiAllocator( void ) throw() { } - - /// Copy constructor does nothing. - inline LokiAllocator( const LokiAllocator& ) throw() { } - - /// Type converting allocator constructor does nothing. - template < typename Type1 > - inline LokiAllocator( const LokiAllocator< Type1 > & ) throw() { } - - /// Destructor does nothing. - inline ~LokiAllocator() throw() { } - - /// Convert an allocator<Type> to an allocator <Type1>. - template < typename Type1 > - struct rebind - { - typedef LokiAllocator< Type1 > other; - }; - - /// Return address of reference to mutable element. - pointer address( reference elem ) const { return &elem; } - - /// Return address of reference to const element. - const_pointer address( const_reference elem ) const { return &elem; } - - /** Allocate an array of count elements. Warning! The true parameter in - the call to Allocate means this function can throw exceptions. This is - better than not throwing, and returning a null pointer in case the caller - assumes the return value is not null. - @param count # of elements in array. - @param hint Place where caller thinks allocation should occur. - @return Pointer to block of memory. - */ - pointer allocate( size_type count, const void* hint = 0 ) - { - (void)hint; // Ignore the hint. - void* p = AllocT::Instance().Allocate( count * sizeof( Type ), true ); - return reinterpret_cast< pointer >( p ); - } - - /// Ask allocator to release memory at pointer with size bytes. - void deallocate( pointer p, size_type size ) - { - AllocT::Instance().Deallocate( p, size * sizeof( Type ) ); - } - - /// Calculate max # of elements allocator can handle. - size_type max_size( void ) const throw() - { - // A good optimizer will see these calculations always produce the same - // value and optimize this function away completely. - const size_type max_bytes = size_type( -1 ); - const size_type bytes = max_bytes / sizeof( Type ); - return bytes; - } - - /// Construct an element at the pointer. - void construct( pointer p, const Type& value ) - { - // A call to global placement new forces a call to copy constructor. - ::new( p ) Type( value ); - } - - /// Destruct the object at pointer. - void destroy( pointer p ) - { - // If the Type has no destructor, then some compilers complain about - // an unreferenced parameter, so use the void cast trick to prevent - // spurious warnings. - (void)p; - p->~Type(); - } - -}; - -//----------------------------------------------------------------------------- - -/** All equality operators return true since LokiAllocator is basically a - monostate design pattern, so all instances of it are identical. - */ -template < typename Type > -inline bool operator == ( const LokiAllocator< Type > &, const LokiAllocator< Type > & ) -{ - return true; -} - -/** All inequality operators return false since LokiAllocator is basically a - monostate design pattern, so all instances of it are identical. - */ -template < typename Type > -inline bool operator != ( const LokiAllocator< Type > & , const LokiAllocator< Type > & ) -{ - return false; -} - -//----------------------------------------------------------------------------- - -} // namespace Loki - -#endif // LOKI_ALLOCATOR_INCLUDED diff --git a/shared/loki/AssocVector.h b/shared/loki/AssocVector.h deleted file mode 100644 index 7f259281..00000000 --- a/shared/loki/AssocVector.h +++ /dev/null @@ -1,358 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_ASSOCVECTOR_INC_ -#define LOKI_ASSOCVECTOR_INC_ - -// $Id: AssocVector.h 765 2006-10-18 13:55:32Z syntheticpp $ - - -#include <algorithm> -#include <functional> -#include <vector> -#include <utility> - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVectorCompare -// 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); } -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVector -// An associative vector built as a syntactic drop-in replacement for std::map -// BEWARE: AssocVector doesn't respect all map's guarantees, the most important -// being: -// * iterators are invalidated by insert and erase operations -// * the complexity of insert/erase is O(N) not O(log N) -// * value_type is std::pair<K, V> not std::pair<const K, V> -// * iterators are random -//////////////////////////////////////////////////////////////////////////////// - - -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 - { - 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()) - : Base(alloc), MyCompare(comp) - {} - - 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; - } - - // 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) - { - if ( (pos == begin() || this->operator()(*(pos - 1), val)) && - (pos == end() || this->operator()(val, *pos)) ) - { - return Base::insert(pos, val); - } - return insert(val).first; - } - - 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) - { - iterator i(find(k)); - if (i == end()) return 0; - erase(i); - return 1; - } - - void erase(iterator first, iterator last) - { Base::erase(first, last); } - - void swap(AssocVector& other) - { - Base::swap(other); - MyCompare& me = *this; - MyCompare& rhs = other; - std::swap(me, rhs); - } - - void clear() - { Base::clear(); } - - // observers: - key_compare key_comp() const - { return *this; } - - value_compare value_comp() const - { - const key_compare& comp = *this; - return value_compare(comp); - } - - // 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; - } - - 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; - } - - size_type count(const key_type& k) const - { return find(k) != end(); } - - 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); - } - - iterator upper_bound(const key_type& k) - { - MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - const_iterator upper_bound(const key_type& k) const - { - const MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - std::pair<iterator, iterator> equal_range(const key_type& k) - { - MyCompare& me = *this; - return std::equal_range(begin(), end(), k, me); - } - - 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); - - bool operator<(const AssocVector& rhs) const - { - const Base& me = *this; - const Base& yo = rhs; - return me < yo; - } - - 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 !(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); } - - -// 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/CHANGES b/shared/loki/CHANGES deleted file mode 100644 index 67f6505e..00000000 --- a/shared/loki/CHANGES +++ /dev/null @@ -1,446 +0,0 @@ -_____________________________________ - -Version 0.1.7 -January 2009 -_____________________________________ - -General: - - Fixed makefiles for GNU/kFreeBSD, GNU/hurd. (lf) - - Fixed build errors with gcc 4.3 pre-release. (lf) - - Fixed compiler error that occurs when using 64 bit pointers. (rs) - - Added support for Code::Blocks and MSVC 9. (rs, pk) - - Added more unit tests (rs) - - Several other bug fixes (rs, pk) - -Checker: - - Added for this release. (rs) - - Added test project. (rs) - -CheckReturn: - - Added for this release. (rs, pk) - - Added test project. (rs + pk) - -flex_string: - - Fixed bugs in several functions and storage policies. (aa, rs, jfg) - -LevelMutex: - - Added for this release. (rs) - - Added unit tests for LevelMutex. (rs) - -SafeBits: - - Added for this release. (rs, fp) - - Added unit tests for SafeBits. (rs, fp) - -SmartPtr: - - Fixed double-delete race condition. (rs) - -StrongPtr: - - Fixed destructor so cleanup is only done once. (rs) - - Fixed test by using class level locking. (lf) - -Threads: - - Add possibility to enable recursive mutex support for pthread (pk) - - Added more atomic functions. (rs) - -Type Traits: - - Added 64 bit support. (cg) - -CVS commits by: - Andrei Alexandrescu (aa) - Guillaume Chatelet (cg) - Lukas Fittl (lf) - Peter Kümmel (pk) - Rich Sposato (rs) - -Contributions by: - Andrei Alexandrescu (aa) - Jean-Francois Bastien (jfb) - Guillaume Chatelet (cg) - Lukas Fittl (lf) - Fedor Pikus (fp) - Peter Kümmel (pk) - Rich Sposato (rs) - -_____________________________________ - -Version 0.1.6 -February 25, 2007 -_____________________________________ - -General: - - CacheFactory added by Guillaume Chatelet - - Factory documentation improved by Guillaume Chatelet - - migrated to subversion (pk) - - Mac linker errors fixed (lf) - - Makefiles can now be called from sub directories (lf) - - Makefiles know includes and recompile if they are changed (linux, macosx) (lf) - - Build all tests except SingletonDll with the static library (linux, macosx) (lf) - - use standard conforming naming, SUN's compiler needs it (pk) - - add Loki:: to LOKI_ macros - - several bug fixes. - -AbstractFactory: - - remove injected friends. (thanks to Sigoure Benoit, pk) - -AssocVector: - - remove injected friends. (thanks to Sigoure Benoit, pk) - -LockingPtr: - - constructor added which gets a std::pair of pointers - to the object and the mutex (pk) - -Pimpl: - - ImplT/PimplT/RimplT renamed to a more readable version: ImplOf (pk) - -Register: - - also produce a informative LOKI_CHECK_CLASS_IN_LIST error message with GCC (pk) - -SafeFormat: - - add writing to ostream, by Tom Browder (pk) - - add unsigned long version for Windows, (Thanks to ShenLei, pk) - -Sequence: - - Also compiles with Aix - - switched to recursive implementation - -Singleton - - example: move instantiation to the source file - fixes linker error with gcc 4.0.1 on the mac, - (Thanks to Idar Tollefsen and Sam Miller, pk) - - 64 bit linker error fixed (lf) - -SmallObj: - - compiler errors on SUN fixed (pk) - - more documentation (rs) - - more tests (rs) - - AIX fixed, (thanks to Dieter Rosch, pk) - -StrongPtr: - - Added typedef so LockableTwoRefCounts uses thread-safe allocator. (rs) - - AIX fixed, (thanks to Dieter Rosch, pk) - - linker error when using threads fixed (pk) - -Threads: - - reentrance support added to the pthread mutex (Thanks to Shen Lei, pk) - - -CVS commits by Guillaume Chatelet (gc), Lukas Fittl (lf), Peter Kümmel (pk), Rich Sposato (rs) - - -_____________________________________ - -Version 0.1.5 -June 19, 2006 -_____________________________________ - -General: - - operator== added to Functor, initiated by Eric Beyeler (pk) - - new Strong/Weak smart pointer added. (rs) - - loki.spec (Thanks to Regis Desgroppes and Andreas Scherer, pk) - - build shared lib also on mac osx (Thanks to Sam Miller, lf) - - added MinGW .dev files for the library (rs) - - some makefile improvements (Thanks to Sam Miller, lf) - - adding an XCode build project (kx) - - -flex_string: - - compare bug fixed in flex_string_shell.h (Thanks to David A. Capello, pk) - -Function: - - test is doesn't need boost any more (pk) - - wrong default parameter fixed (pk) - -OrderedStatic: - - undef all min/max macros (Thanks to Shen Lei, pk) - -Singleton: - - Singleton<> moved into correct namespace (Thanks to Sam Miller, pk) - -SmartPtr: - - patch for RedHat 9: undefined uintptr_t (Thanks to Regis Desgroppes, pk) - - more tests (rs) - - bugs 1452805 and 1451835 fixed (rs) - - addded HeapStorage policy as mentioned in Feature Request 1441024 (rs) - - added MinGW test project for SmartPtr (rs) - - -CVS commits by Rich Sposato (rs), Lukas Fittl (lf), -Christopher Knox (kx), and Peter Kümmel (pk) - - - -_____________________________________ - -Version 0.1.4 -March 8, 2006 -_____________________________________ - -General: - - helper templates for Pimpl/Rimpl implementations added (pk) - - improved Makefiles (lf) - - improved make.msvc.bat files (pk) - - cvs LOG keywords added (rs) - - removed old c style casts (lf) - - more warning enabled on gcc (lf) - - new header added: ConstPolicy.h (rs,pk) - - new header added: RefToValue.h (rs,pk) - - standard RPM specification file for integrated installation - on OpenSUSE Linux added (Thanks to Andreas Scherer, pk) - - using Loki as shared library is now possible (pk,lf) - - Register.h added (pk) - - -Function: - - guard including (pk) - - test stsic functions (pk) - - test LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT (pk) - -Functor: - - Added explicit call to base copy-constructor (rs) - - Changed base class from SmallObject to SmallValueObject. (Thanks to Sam Miller, rs) - - add possibility to disable inheritance from SmallValueObject: LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT (pk) - -ScopeGuard: - - naming conflict with SmartPtr removed (rs,pk) - - ByRef moved to RefByVale (rs,pk) - -Singleton: - - support of allocators with a standard interface added (Thanks to Miguel A. Figueroa-Villanueva, pk) - - convenience template Singleton added for shared libraries (Thanks to Marcus Lindblom, pk) - - example added which shows how to use Singletons with shared libraries added (Thanks to Marcus Lindblom, pk) - -SmartPtr: - - supports propagating constness by additional policy (rs,pk) - - ArrayStorage policy added (Thanks to Sam Miller, pk) - - fix in RefCounted for Mac OSX gcc 4.0.0 (Thanks to Sam Miller, pk) - - RefCounted ported to 64 bit (pk) - - add mutex policy (pk) - - new test code (rs) - - RecjectNullStrict const member function added (Thanks to Sam Miller, pk) - - Moved a monolithic RefLinkedBase class from header file to new source file. (rs) - - ByRef moved to RefToVale (rs,pk) - - Fixed bug 1425890. Last SmartPtr in linked chain NULLs its prev & next - pointers to prevent infinite recursion. Added asserts. (rs) - - Bug fix: infinite recursion in SmartPtr destructor (rs) - -LockingPtr: - - wrong return types fixed (rs) - - add mutex policy (rs,pk) - - supports now propagating constness (pk,rs) - - macro switch LOKI_DEFAULT_CONSTNESS added for propagating constness (pk) - - multi threaded example added - -SafeFormat: - - definition moved to src/SafeFormat.cpp, it's now part of the library - -Singleton: - - add mutex policy (pk) - -SmallObj: - - add mutex policy (pk) - - Added check for memory leak inside destructor. (Thanks to Kwak Jae Hyuk, rs) - -Threads: - - Mutex added (rs,pk) - - use Loki::Mutex instead of win32/posix mutexes in threading classes (rs,pk) - - -CVS commits by Rich Sposato (rs), Lukas Fittl (lf) -and Peter Kümmel (pk) - - - -_____________________________________ - -Version 0.1.3 -January 9, 2006 -_____________________________________ - -General: - - LockPtr added (rs) - - ScopeGuard added (pk,rs) - - improved Makefiles (lf,pk) - - several gcc fixes and removed warnings by Lukas Fittl (lf) - - tested on 64-bit Linux (pk) - - MS Visual C++ 2005 project files added (pk) - - now also the ms toolkit 2003 generates a library (pk) - -OrderedStatic: - - point operator added (pk) - -SafeFormat: - - moved into namespace Loki (pk) - - 64 bit problems fixed (Thanks to Zak Kipling) - - ported to 64-bit Windows, not tested (pk) - - Printf/SPrintfing of std::strings added (pk) - - all warnings removed gcc and msvc (pk) - - use snprintf for "%p" - - test program: speed comparison added (pk) - -SmallObject: - - added functions to check for memory corruption (rs) - - more fine tuning (rs) - - warnings removed (pk) - -TypeTraits: - - bug 1388477 fixed (pk) - -flex_string: - - fixed compare bug by updating (Thanks to Justin Matthews, pk) - - fixed seg faults on Linux and Windows (pk) - - improved error reporting of the test program (pk) - -SmartPtr: - - make object level locking possible (Thanks to Ryan Smith, pk) - -BindFirst: - - store Functor arguments by value (bug 1383566) (pk) - -Visitor: - - add support for visiting constant member functions (pk) - - example added (pk) - -ScopeGuard: - - example added (pk) - - -CVS commits by Rich Sposato (rs), Lukas Fittl (lf) -and Peter Kümmel (pk) - - -_____________________________________ - -Version 0.1.2 -November 16, 2005 -_____________________________________ - -General: - - changes to compile under Linux (Thanks to David Lawrence, pk) - - more doxygen documentation, modules added (rs, pk) - -SmartPtr: - - three year old bugs 626407 and 541846 fixed: - Assertion with SmartPtr<T, LinkedRef> (pk) - SmartPtr and COMRefCounted (Thanks to James Mclaren, pk) - -Typelists: - - it's now possible to completely disable the - LOKI_TYPELIST_ macros (pk) - - marco definitions moved to a separate file (pk) - -Factory: - - Factory now protects its private data (pk) - - new method to get the keys: - std::vector<IdType> RegisteredIds() (pk) - -Functor: - - TR1 methods added: empty() and clear() (pk) - -Function: - - boost/TR1 like Function template with - improved member function pointer usage (pk) - - tested with boost's function_test.cpp - -Sequence: - - small change in usage: use e.g. Functor<void,Seq<bool &> > - instead of Functor<void,Seq<bool &>::Type > - -SmallObjects: - - comparison of new/malloc/std::allocator/boost::object_pool (rs, pk) - - #undef LOKI_SMALL_OBJECT_USE_NEW_ARRAY when using a ms compiler (pk) - - new lifetimes in namespace LongevityLifetime to manage dependencies: - DieAsSmallObjectParent and DieAsSmallObjectClient (pk) - - no memory leaks when using SmallObjects (pk) - - new default lifetime is DieAsSmallObjectParent (pk) - -Threads: - - threads on POSIX systems (Thanks to Ilya Volvovski ,pk) - - small regression test program (pk) - -Singleton: - - new lifetime: FollowIntoDeath (pk) - - new namespace LongevityLifetime with lifetimes DieLast, DieFirst, - DieDirectlyBeforeLast, and function SingletonFixedLongevity (pk) - - new implementation for SetLongevity (pk) - - example programs (pk) - - -CVS commits by Rich Sposato (rs) and Peter Kümmel (pk) - - - -_____________________________________ - -Version 0.1.1 -October 17, 2005 -_____________________________________ - -Singleton: - - wrong ordered longevity fixed (Thanks to Kwak Jae Hyuk, pk) - - less warnings with msvc (Thanks to John Bates, pk) - - new policy, DeletableSingleton, from Curtis Krauskopf, - see also CUJ article 'Creating Dynamic Singletons & the Loki Library',(pk) - -AssocVector: - - hinted insert does now preserve ordering (Thanks to Christopher Twigg, pk) - - additional 'hinted insert' test for Regression test by Christopher Twigg (pk) - - fix name look up (Thanks to Markus Werle, pk) - -SmallObj: - - several improvements (rs) - - more documentation (rs) - - improved SmallBench (rs, pk) - -Longevity: - - example added (pk) - - additional example similar to that of the book, by Curtis Krauskopf (pk) - -OrderedStatic: - - a proposal to solve the 'static initialization ordered fiasco' problem (pk) - -Sequence: - - a proposal to replace the LOKI_TYPELIST_XX macros with a template implementation (pk) - - e.g.: LOKI_TYPELIST_1(int) becomes Seq<int>::Type - inspired by the functional language OPAL (pk) - - -CVS commits by Rich Sposato (rs) and Peter Kümmel (pk) - - - -_____________________________________ - -Version 0.1.0 -September 29, 2005 -_____________________________________ - -General: - - version numbering started - - new directory structure - - Andrei's yasli, flex_string, and SafePrint added (pk) - - all macros now in the LOKI "namespace", e.g.: - TYPLELIST_1 -> LOKI_TYPELIST_1 (rs, pk) - - Makefiles added: tested with gcc 3.4 (mingw, cygwin), - msvc 8.0, and the toolkit (pk) - - added some documentation (rs) - - several bug fixes (pk) - - added a cvs-list to sourceforge where you can see all changes (pk) - -SmallObjects: - - new implementation (rs) - -Factory: - - works now with parameters (pk) - - regression test added (Thanks to Kalle Rutanen, pk) - -TypeTraits: - - isMemberPointer, isFunction added (Thanks to Kalle Rutanen, pk) - - regression test added (Thanks to Kalle Rutanen, pk) - -Threading: - - new macros for better thread support (win32): - LOKI_CLASS_LEVEL_THREADING and LOKI_OBJECT_LEVEL_THREADING (pk) - - -CVS commits by Rich Sposato (rs) and Peter Kümmel (pk) - diff --git a/shared/loki/CachedFactory.h b/shared/loki/CachedFactory.h deleted file mode 100644 index dc5a76ae..00000000 --- a/shared/loki/CachedFactory.h +++ /dev/null @@ -1,1179 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2006 by Guillaume Chatelet -// -// 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 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 -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_CACHEDFACTORY_INC_ -#define LOKI_CACHEDFACTORY_INC_ - -// $Id: CachedFactory.h 950 2009-01-26 19:45:54Z syntheticpp $ - -#include <functional> -#include <algorithm> -#include <iostream> -#include <vector> -#include <iterator> -#include <map> -#include <cassert> -#include <loki/Key.h> - -#ifdef DO_EXTRA_LOKI_TESTS -#define D( x ) x -#else -#define D( x ) ; -#endif - -#if defined(_MSC_VER) || defined(__CYGWIN__) -#include <time.h> -#endif - -/** - * \defgroup FactoriesGroup Factories - * \defgroup CachedFactoryGroup Cached Factory - * \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 - * CachedFactory will surely speedup the execution. - */ -namespace Loki -{ -/** - * \defgroup EncapsulationPolicyCachedFactoryGroup Encapsulation policies - * \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";} -}; - -/** - * \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; - } - - 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; - } - - 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; ) - } -}; - -/** - * \defgroup EvictionPolicyCachedFactoryGroup Eviction policies - * \ingroup CachedFactoryGroup - * \brief Gathers informations about the stored objects and choose a - * candidate for eviction. - */ - -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() - { - 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 > -{ -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]); - } - - 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: - 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 -{ -private: - unsigned allocated, created, hit, out, fetched; -protected: - SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0) - { - } - - 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) - { - cout << "## Overall efficiency " << 100 * double(hit) / fetched << "%" << endl; - cout << "############################" << endl; - } - 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 - { - // 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) - { - 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; } - }; - - // 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) - { - 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 - { - 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 - } - -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 >() - ); - } - } - - /////////////////////////////////// - // Acts as the proxy pattern and // - // forwards factory methods // - /////////////////////////////////// - - 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); - } - - /// 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)) - { - 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); - } - - ProductReturn CreateObject(const IdentifierType& id, - Parm1 p1, Parm2 p2) - { - 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); - } - - 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)) - { - 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) - { - 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); - } - - 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)) - { - 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) - { - 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); - } - - 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)) - { - 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); - } - - 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)) - { - 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) - { - 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); - } - - 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)) - { - 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) - { - 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); - } - - 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)) - { - 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) - { - 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); - } - - 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)) - { - 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); - } - - 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)) - { - 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 deleted file mode 100644 index c0a65aa5..00000000 --- a/shared/loki/CheckReturn.h +++ /dev/null @@ -1,165 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2007 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// - -#ifndef LOKI_CHECK_RETURN_INC_ -#define LOKI_CHECK_RETURN_INC_ - -// $Id$ - - -#include <assert.h> -#include <stdio.h> -#include <stdexcept> - - -namespace Loki -{ - -// ---------------------------------------------------------------------------- - -//////////////////////////////////////////////////////////////////////////////// -/// \class CheckReturn -/// -/// \par Purpose -/// C++ provides no mechanism within the language itself to force code to -/// check the return value from a function call. This simple class provides -/// a mechanism by which programmers can force calling functions to check the -/// return value. Or at least make them consciously choose to disregard the -/// return value. If the calling function fails to use or store the return -/// value, the destructor calls the OnError policy. -/// -/// \par Template Parameters -/// CheckReturn has two template parameters, Value and OnError. -/// - Value is the return type from the function. CheckReturn stores a copy of -/// it rather than a reference or pointer since return value could be local to -/// a function. CheckReturn works best when the return type is a built-in -/// primitive (bool, int, etc...) a pointer, or an enum (such as an error -/// condition enum). It can work with other types that have cheap copy -/// operations. -/// - OnError is a policy class indicating how to handle the situation when a -/// caller does not check or copy the returned value. Loki provides some -/// policy classs and you may also write your own. For example, you can write -/// a policy to create a message box when the function ignores the return value. -/// That would quickly tell you places where code ignores the function call. -/// If your write your own, you only need a templated class or struct with a -/// public function named "run" that accepts a reference to a const value. -/// -/// @par Provided Policy Classes -/// - IgnoreReturnValue Deliberately ignores when the caller ignores the return value. -/// - TriggerAssert Asserts in debug builds if the caller ignores the return value. -/// - FprintfStderr Prints out an error message if the caller ignores the return value. -/// - ThrowTheValue Throws the ignored value as an exception. -/// - ThrowLogicError Throws a logic_error exception to indicate a programming error. -//////////////////////////////////////////////////////////////////////////////// - - -template<class T> -struct IgnoreReturnValue -{ - static void run(const T&) - { - /// Do nothing at all. - } -}; - -template<class T> -struct ThrowTheValue -{ - 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" ); - } -}; - -template<class T> -struct TriggerAssert -{ - 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"); - } -}; - - - -template < class Value , template<class> class OnError = TriggerAssert > -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; - } - -private: - /// Default constructor not implemented. - CheckReturn( void ); - - /// Copy-assignment operator not implemented. - CheckReturn& operator = ( const CheckReturn& that ); - - /// Copy of returned value. - Value m_value; - - /// Flag for whether calling function checked return value yet. - mutable bool m_checked; -}; - -// ---------------------------------------------------------------------------- - -} // namespace Loki - -#endif // end file guardian - -// $Log$ - diff --git a/shared/loki/Checker.h b/shared/loki/Checker.h deleted file mode 100644 index 64579d2f..00000000 --- a/shared/loki/Checker.h +++ /dev/null @@ -1,516 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// The Loki Library -// Copyright (c) 2008 Rich 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 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 warranty. -// -//////////////////////////////////////////////////////////////////////////////// - -// $Id$ - -/// @file Checker.h This file provides Loki's Checker facility. - - -// ---------------------------------------------------------------------------- - -#ifndef LOKI_CHECKER_H_INCLUDED -#define LOKI_CHECKER_H_INCLUDED - -#include <exception> // needed for calls to uncaught_exception. -#include <assert.h> - - -namespace Loki -{ - -/** @par ContractChecker and StaticChecker Overview - The ContractChecker and StaticChecker classes have two purposes: - - provide a mechanism by which programmers can determine which functions - violate class/data invariants, - - and determine which exception safety a function provides. - - @par Class & Data Invariants - The ContractChecker and StaticChecker define invariants as "expressions that - are true for particular data". They uses a function which returns true if all - data are valid, and returns false if any datum is invalid. This is called the - validator function, and the host class or function provides a pointer to it. - The validator could also assert for any invariant which fails rather than - return false. If the validator is a static member function, you can use it - with checkers in any function, but especially standalone functions and class - static functions. If the validator is a non-static member function, you can - use it only within non-static member functions. - - @par Exception Safety Levels - Years ago, David Abrahams formalized a framework for assessing the exception - safety level a function provides. His framework describes three levels of - guarantees. Any function which does not provide any of these levels is - considered unsafe. ContractChecker and StaticChecker determine a function's - safety level through the use of policy classes. Checker's policy classes can - show if a function provides any of these three guarantees. Since there is no - universal way to detect leaks, this facility provides no mechanism for finding - leaks, but users may create their own validators which do. StaticChecker's - policy classes only provide direct checking for the no-throw and invariant - guarantees. With some finesse, a programmer can write a validator for - StaticChecker that checks for the Strong guarantee. - - - No-throw guarantee: A function will not throw any exceptions. - - Strong guarantee: A function will not change data if an exception occurs. - (Which I call the no-change guarantee.) - - Basic guarantee: A function will not leak resources and data will remain - in a valid state if an exception occurs. (Which I call either the no-leak - or no-break guarantee depending on context.) - */ - -// ---------------------------------------------------------------------------- - -/** @class CheckForNoThrow - - @par Exception Safety Level: - This exception-checking policy class for ContractChecker asserts if an - exception exists. Host classes can use this to show that a member function - provides the no-throw exception safety guarantees. - - @par Requirements For Host Class: - This policy imposes no requirements on a host class. - */ -template < class Host > -class CheckForNoThrow -{ -public: - - inline explicit CheckForNoThrow( const Host* ) {} - - inline bool Check( const Host* ) const - { - const bool okay = ( !::std::uncaught_exception() ); - assert( okay ); - return okay; - } -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckForNoChange - - @par Exception Safety Level: - This exception-checking policy class for ContractChecker asserts only if a - copy of the host differs from the host object when an exception occurs. Host - classes can use this policy to show which member functions provide the strong - exception guarantee. - - @par Requirements: - This policy requires hosts to provide both the copy-constructor and the - equality operator, and is intended for classes with value semantics. - equality operator. - */ - -template < class Host > -class CheckForNoChange -{ -public: - - inline explicit CheckForNoChange( const Host* host ) : - m_compare( *host ) {} - - inline bool Check( const Host* host ) const - { - const bool okay = ( !::std::uncaught_exception() ) - || ( m_compare == *host ); - assert( okay ); - return okay; - } - -private: - Host m_compare; -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckForNoChangeOrThrow - - @par Exception Safety Level: - This exception-checking policy class for ContractChecker asserts either if a - copy of the host differs from the original host object, or if an exception - occurs. Host classes can use this policy to show which member functions provide - the no-throw exception guarantee, and would never change data anyway. - - @par Requirements For Host Class: - This policy requires hosts to provide both the copy-constructor and the - equality operator, and is intended for classes with value semantics. - */ - -template < class Host > -class CheckForNoChangeOrThrow -{ -public: - - inline explicit CheckForNoChangeOrThrow( const Host* host ) : - m_compare( *host ) {} - - inline bool Check( const Host* host ) const - { - bool okay = ( !::std::uncaught_exception() ); - assert( okay ); - okay = ( m_compare == *host ); - assert( okay ); - return okay; - } - -private: - Host m_compare; -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckForEquality - - @par Exception Safety Level: - This exception-checking policy class for ContractChecker asserts if a copy of the host differs from the host object regardless of whether an exception occurs. - Host classes can use this policy to show which member functions never change - data members, and thereby provide the strong exception safety level by default. - - @par Requirements For Host Class: - This policy requires hosts to provide both the copy-constructor and the - equality operator, and is intended for classes with value semantics. - */ - -template < class Host > -class CheckForEquality -{ -public: - - inline explicit CheckForEquality( const Host* host ) : - m_compare( *host ) {} - - inline bool Check( const Host* host ) const - { - const bool okay = ( m_compare == *host ); - assert( okay ); - return okay; - } - -private: - Host m_compare; -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckForNothing - - @par Exception Safety Level: - This exception-checking policy class for ContractChecker does nothing when - called. Host classes can use this to show which member functions provide - neither the strong nor no-throw exception guarantees. The best guarantee such - functions can provide is that nothing gets leaked. - - @par Requirements For Host Class: - This policy imposes no requirements on a host class. - */ - -template < class Host > -class CheckForNothing -{ -public: - inline explicit CheckForNothing( const Host* ) {} - inline bool Check( const Host* ) const { return true; } -}; - -// ---------------------------------------------------------------------------- - -/** @class ContractChecker - This class determines if a function violated any class invariant, but it also - determines if a function fulfills its contract with client code. In the - "Design by Contract" paradigm, each function has certain pre-conditions and - post-conditions which may differ from the class invariants. This asserts if a - check for an invariant fails as well as if any pre- or post-condition fails. - It also demonstrate which exception safety level a function provides. - - @par Usage - -# Implement a function that checks each class invariant. The function must - have the signature similar to the Validator type. Something like: - "bool Host::IsValid( void ) const;" - - The function should return true if everything is okay, but false if - something is wrong. - - Or it could assert if anything is wrong. - - Ideally, it should be private. - -# Implement similar functions to check for pre-conditions and post-conditions. - Functions which verify pre-conditions and post-conditions do not need to - check all class invariants, just conditions specific to certain public - functions in the host class. - -# Declare some typedef's inside the class declaration like these. Make one - typedef for each exception policy you use. I typedef'ed the CheckForNothing - policy as CheckInvariants because even if a function can't provide either the - no-throw nor the no-change policies, it should still make sure the object - remains in a valid state. - - typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNoThrow > CheckForNoThrow; - - typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNoChange > CheckForNoChange; - - typedef ::Loki::ContractChecker< Host, ::Loki::CheckForEquality > CheckForEquality; - - typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNothing > CheckInvariants; - -# Construct a checker near the top of each member function - except in the - validator member function. Pass the this pointer and the address of your - validator function into the checker's constructor. You may also pass in pointers - to function which check pre- and post-conditions. - - If the function never throws, then use the CheckForNoThrow policy. - - If the function never changes any data members, then use CheckForEquality - policy. - - If the function's normal execution flow changes data, but must make sure - data remains unchanged when any exceptions occur, then use the - CheckForNoChange policy. - - Otherwise use the CheckInvariants policy. - -# Recompile a debug version of your program, run the program and all the unit - tests, and look for which assertions failed. - */ - -template -< -class Host, - template < class > class ExceptionPolicy - > -class ContractChecker : public ExceptionPolicy< Host > -{ - /// Shorthand for the ExceptionPolicy class. - typedef ExceptionPolicy< Host > Ep; - -public: - - /// Signature for the validation function. - typedef bool ( Host:: * Validator )( void ) const; - - /** The constructor makes sure the host is valid at the time the checker - was created, thus insuring the host object was not corrupt from the start. - @par host Pointer to host object. - @par validator Pointer to function that checks class invariants. - @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 ) : - Ep( host ), - m_host( host ), - m_validator( validator ), - m_pre( pre ), - m_post( post ) - { - assert( Check() ); - if ( 0 != m_pre ) - assert( ( m_host->*( m_pre ) )() ); - } - - /** The destructor checks if any Host invariants failed, and then calls the - ExceptionPolicy's Check function to determine what to do in case of an - exception. - */ - inline ~ContractChecker( void ) - { - assert( Check() ); - if ( 0 != m_post ) - assert( ( m_host->*( m_post ) )() ); - assert( Ep::Check( m_host ) ); - } - - /** This first checks the invariants for ContractChecker, and then calls the - validator function for the host to make sure no class invariants were - broken by the host within the Host's member function body. The host - member function can call Check directly to verify the object remains valid - at any time. This does not care if the pre- and post-condition validator - pointers are null since a host class may pass in NULL pointers for either - to indicate the pre-conditions or post-conditions are the same as the - overall class invariants. - */ - inline bool Check( void ) const - { - assert( 0 != this ); - assert( 0 != m_host ); - assert( 0 != m_validator ); - // Now that this confirms the pointers to the host and validation - // functions are not null, go ahead and validate the host object. - const bool okay = ( m_host->*( m_validator ) )(); - assert( okay ); - return okay; - } - -private: - - /// Default constructor is not implemented. - ContractChecker( void ); - /// Copy constructor is not implemented. - ContractChecker( const ContractChecker& ); - /// Copy-assignment operator is not implemented. - ContractChecker& operator = ( const ContractChecker& ); - - /// Pointer to the host object. - const Host* m_host; - - /// Pointer to member function that checks Host object's invariants. - Validator m_validator; - - /// Pointer to member function that checks Host object's pre-conditions. - Validator m_pre; - - /// Pointer to member function that checks Host object's post-conditions. - Validator m_post; - -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckStaticForNoThrow - - @par Exception Safety Level: - This exception-checking policy class for StaticChecker asserts if an exception - exists. Functions can use this to show they provide the no-throw exception - safety guarantee. - */ -class CheckStaticForNoThrow -{ -public: - inline bool Check( void ) - { - const bool okay = !::std::uncaught_exception(); - assert( okay ); - return okay; - } -}; - -// ---------------------------------------------------------------------------- - -/** @class CheckStaticForNothing - - @par Exception Safety Level: - This exception-checking policy class for StaticChecker does nothing when called. - Functions can use this to show they might provide the weak exception guarantee. - The best guarantee such functions can provide is that nothing gets leaked. - */ -class CheckStaticForNothing -{ -public: - inline bool Check( void ) { return true; } -}; - -// ---------------------------------------------------------------------------- - -/** @class StaticChecker - This class checks if a function provides the no-throw exception safety level - and if the function violated any invariants. Invariants for stand-alone and - static functions act as pre-conditions and post-conditions. - - @par Usage - -# Implement a function that checks the invariants associated with a function, - or with the static data for a class. The function must - have the signature similar to the Validator type. Something like: - "static bool Host::StaticIsValid( void );" or "bool IsOkay( void );" - - The function should return true if everything is okay, but false if - something is wrong. - - Or it could assert if anything is wrong. - -# If the checker is for static functions within a class, declare typedef's - inside the class declaration like these. Make one typedef for each policy - you use. I typedef'ed the CheckForNothing policy as CheckInvariants because - even if a function can't provide the no-throw guarantee, it should still - make sure that static data remains in a valid state. - - typedef ::Loki::StaticChecker< ::Loki::CheckForNoThrow > CheckStaticForNoThrow; - - typedef ::Loki::StaticChecker< ::Loki::CheckForNothing > CheckStaticInvariants; - -# Construct a checker near the top of each member function - except in the - validator member function. Pass the address of your validator function into - the checker's constructor. - - If the function never throws, then use the CheckForNoThrow policy. - - Otherwise use the CheckInvariants policy. - -# Recompile a debug version of your program, run it, and see if an assertion - fails. - */ - -template -< -class ExceptionPolicy -> -class StaticChecker : public ExceptionPolicy -{ - /// Shorthand for the ExceptionPolicy class. - typedef ExceptionPolicy Ep; - -public: - - /// Signature for the validation function. - typedef bool ( * Validator )( void ); - - /** The constructor makes sure the host is valid at the time the checker - was created, thus insuring the host object was not corrupt from the start. - @par validator Pointer to function that checks class invariants. - @par pre Optional pointer to function that checks pre-conditions. - @par post Optional pointer to function that checks post-conditions. - */ - inline explicit StaticChecker( Validator validator, - Validator pre = 0, Validator post = 0 ) : - Ep(), - m_validator( validator ), - m_pre( pre ), - m_post( post ) - { - assert( Check() ); - if ( 0 != m_pre ) - assert( m_pre() ); - } - - /** The destructor checks if any Host invariants failed, and then calls the - ExceptionPolicy's Check function to determine what to do in case of an - exception. - */ - inline ~StaticChecker( void ) - { - assert( Check() ); - if ( 0 != m_post ) - assert( m_post() ); - assert( Ep::Check() ); - } - - /** This first checks its own invariants, and then calls the validator - function to make sure no invariants were broken by the function which - created this checker. That function can call Check directly to verify the - data remains valid at any time. This does not care if the pre- and post- - condition validator pointers are null since a host class may pass in NULL - pointers for either to indicate the pre-conditions or post-conditions are - the same as the overall class invariants. - */ - inline bool Check( void ) const - { - assert( 0 != this ); - assert( 0 != m_validator ); - // Now that this confirms the pointers to the host and validation - // functions are not null, go ahead and validate the host object. - const bool okay = m_validator(); - assert( okay ); - return okay; - } - -private: - - /// Default constructor is not implemented. - StaticChecker( void ); - /// Copy constructor is not implemented. - StaticChecker( const StaticChecker& ); - /// Copy-assignment operator is not implemented. - StaticChecker& operator = ( const StaticChecker& ); - - /// Pointer to member function that checks Host object's invariants. - Validator m_validator; - - /// Pointer to member function that checks Host object's pre-conditions. - Validator m_pre; - - /// Pointer to member function that checks Host object's post-conditions. - Validator m_post; - -}; - -// ---------------------------------------------------------------------------- - -}; // end namespace Loki - -#endif diff --git a/shared/loki/ConstPolicy.h b/shared/loki/ConstPolicy.h deleted file mode 100644 index 1adb227a..00000000 --- a/shared/loki/ConstPolicy.h +++ /dev/null @@ -1,61 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_CONST_POLICY_INC_ -#define LOKI_CONST_POLICY_INC_ - -// $Id: ConstPolicy.h 769 2006-10-26 10:58:19Z syntheticpp $ - - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// @note These policy classes are used in LockingPtr and SmartPtr to define -/// how const is propagated from the pointee. -//////////////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////////////// -/// \class DontPropagateConst -/// -/// \ingroup ConstGroup -/// Don't propagate constness of pointed or referred object. -//////////////////////////////////////////////////////////////////////////////// - -template< class T > -struct DontPropagateConst -{ - typedef T Type; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class PropagateConst -/// -/// \ingroup ConstGroup -/// Propagate constness of pointed or referred object. -//////////////////////////////////////////////////////////////////////////////// - -template< class T > -struct PropagateConst -{ - typedef const T Type; -}; - -// default will not break existing code -#ifndef LOKI_DEFAULT_CONSTNESS -#define LOKI_DEFAULT_CONSTNESS ::Loki::DontPropagateConst -#endif - -} // end namespace Loki - -#endif // end file guardian diff --git a/shared/loki/DataGenerators.h b/shared/loki/DataGenerators.h deleted file mode 100644 index 7ac697af..00000000 --- a/shared/loki/DataGenerators.h +++ /dev/null @@ -1,113 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Data Generator by Shannon Barber -// This code DOES NOT accompany the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// -// Code covered by the MIT License -// 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_DATAGENERATORS_INC_ -#define LOKI_DATAGENERATORS_INC_ - -// $Id: DataGenerators.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -#include "Typelist.h" - -//Reference version - -/************************************************************************************ -// class template GenData -// Iteratates a Typelist, and invokes the functor GenFunc<T> -// for each type in the list, passing a functor along the way. -// The functor is designed to be an insertion iterator which GenFunc<T> -// can use to output information about the types in the list. -// - -Example Use - -template<typename T> -struct ExtractDataType - { - some_type operator()() - { - return create_value_from_type<T>; - } - }; - -Loki::IterateTypes<parameter_tl, ExtractDataType> gendata; -std::vector<some_type> stuff; -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> -{ - 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 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<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 -}//ns Loki - -#endif // end file guardian - diff --git a/shared/loki/EmptyType.h b/shared/loki/EmptyType.h deleted file mode 100644 index 0f60c894..00000000 --- a/shared/loki/EmptyType.h +++ /dev/null @@ -1,49 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_EMPTYTYPE_INC_ -#define LOKI_EMPTYTYPE_INC_ - -// $Id: EmptyType.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class EmptyType -// Used as a class type that doesn't hold anything -// 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; -} -} - -#endif // end file guardian - diff --git a/shared/loki/Factory.h b/shared/loki/Factory.h deleted file mode 100644 index bf31afc5..00000000 --- a/shared/loki/Factory.h +++ /dev/null @@ -1,1084 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// Copyright (c) 2005 by Peter Kuemmel -// This code DOES NOT accompany the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// -// Code covered by the MIT License -// 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_FACTORYPARM_INC_ -#define LOKI_FACTORYPARM_INC_ - -// $Id: Factory.h 788 2006-11-24 22:30:54Z clitte_bbt $ - - -#include "LokiTypeInfo.h" -#include "Functor.h" -#include "AssocVector.h" -#include "SmallObj.h" -#include "Sequence.h" - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4702) -//unreachable code if OnUnknownType throws an exception -#endif - -/** - * \defgroup FactoriesGroup Factories - * \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. - * Factory Method, one of the patterns from the Design Patterns book, handles - * this problem by defining a separate method for creating the objects, which - * subclasses can then override to specify the derived type of product that will - * be created. - * <br> - * More generally, the term Factory Method is often used to refer to any method - * 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> - * 2. aFactory.Register( 1, createProductNull );<br> - * 3. aFactory.CreateObject( 1 ); <br> - * </code><br> - * <br> - * - 1. The declaration<br> - * You want a Factory that produces AbstractProduct.<br> - * The client will refer to a creation method through an int.<br> - * - 2.The registration<br> - * The code that will contribute to the Factory will now need to declare its - * 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> - * {<br> - * return new Product<br> - * }<br> - * </code><br> - * - 3. The use<br> - * Now the client can create object by calling the Factory's CreateObject method - * with the right identifier. If the ProductCreator were to have arguments - * (<i>ie :Product* createProductParm( int a, int b )</i>) - */ - -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 - * - */ - -template <typename IdentifierType, class AbstractProduct> -struct DefaultFactoryError -{ - struct Exception : public std::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 - - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; -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; -}; - -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; -}; - -#ifndef LOKI_DISABLE_TYPELIST_MACROS - -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; -}; - -#endif //LOKI_DISABLE_TYPELIST_MACROS - - -//////////////////////////////////////////////////////////////////////////////// -/// \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_() - { - } - - ~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> -{ -public: - bool Register(const IdentifierType& id, ProductCreator creator) - { - return associations_.insert( - typename IdToProductMap::value_type(id, creator)).second != 0; - } - - bool Unregister(const IdentifierType& id) - { - return associations_.erase(id) != 0; - } - - 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_; -}; - -#endif //#define ENABLE_NEW_FACTORY_CODE - -/** - * \defgroup CloneFactoryGroup Clone Factory - * \ingroup FactoriesGroup - * \brief Creates a copy from a polymorphic object. - * - * \class CloneFactory - * \ingroup CloneFactoryGroup - * \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> -{ -public: - bool Register(const TypeInfo& ti, ProductCreator creator) - { - return associations_.insert( - typename IdToProductMap::value_type(ti, creator)).second != 0; - } - - bool Unregister(const TypeInfo& id) - { - return associations_.erase(id) != 0; - } - - AbstractProduct* CreateObject(const AbstractProduct* model) - { - 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)); - } - -private: - typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap; - IdToProductMap associations_; -}; - -} // namespace Loki - - -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - -#endif // end file guardian - diff --git a/shared/loki/Function.h b/shared/loki/Function.h deleted file mode 100644 index 5f388d3c..00000000 --- a/shared/loki/Function.h +++ /dev/null @@ -1,373 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_FUNCTION_INC_ -#define LOKI_FUNCTION_INC_ - -// $Id: Function.h 841 2008-03-24 23:58:28Z rich_sposato $ - - -#define LOKI_ENABLE_FUNCTION - -#include <stdexcept> - -#include <loki/Functor.h> -#include <loki/Sequence.h> - -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) {} - -template<class Host, class Func> -Function(const Host& host, const Func& func) : FBase(host, func) {} - -}; - - -//////////////////////////////////////////////////////////////////////////////// -// macros for the repetitions -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_FUNCTION_BODY \ - \ - Function() : FBase() {} \ - \ - Function(const Function& func) : FBase() \ - { \ - if( !func.empty()) \ - FBase::operator=(func); \ - } \ - \ - 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) {} - - -#define LOKI_FUNCTION_R2_CTOR_BODY \ - \ - : FBase() \ - { \ - if(!func.empty()) \ - FBase::operator=(func); \ - } - - -//////////////////////////////////////////////////////////////////////////////// -// repetitions -//////////////////////////////////////////////////////////////////////////////// - -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 -}; - -}// namespace Loki - -#endif // end file guardian - diff --git a/shared/loki/Functor.h b/shared/loki/Functor.h deleted file mode 100644 index 664af077..00000000 --- a/shared/loki/Functor.h +++ /dev/null @@ -1,1790 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_FUNCTOR_INC_ -#define LOKI_FUNCTOR_INC_ - -// $Id: Functor.h 750 2006-10-17 19:50:02Z syntheticpp $ - - -#include "Typelist.h" -#include "Sequence.h" -#include "EmptyType.h" -#include "SmallObj.h" -#include "TypeTraits.h" -#include <typeinfo> -#include <memory> - -/// \defgroup FunctorGroup Function objects - -#ifndef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT -//#define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT -#endif - -#ifndef LOKI_FUNCTORS_ARE_COMPARABLE -//#define LOKI_FUNCTORS_ARE_COMPARABLE -#endif - - -/// \namespace Loki -/// All classes of Loki are in the Loki namespace -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template FunctorImpl (internal) -//////////////////////////////////////////////////////////////////////////////// - -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>() {} -#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; - } - - -#ifdef LOKI_FUNCTORS_ARE_COMPARABLE - - virtual bool operator==(const FunctorImplBase&) const = 0; - -#endif - -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// macro LOKI_DEFINE_CLONE_FUNCTORIMPL -// Implements the DoClone function for a functor implementation -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_CLONE_FUNCTORIMPL(Cls) \ - virtual Cls* DoClone() const { return new Cls(*this); } - -//////////////////////////////////////////////////////////////////////////////// -// class template FunctorImpl -// The base class for a hierarchy of functors. The FunctorImpl class is not used -// directly; rather, the Functor class manages and forwards to a pointer to -// FunctorImpl -// You may want to derive your own functors from FunctorImpl. -// 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; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -#ifndef LOKI_DISABLE_TYPELIST_MACROS - -//////////////////////////////////////////////////////////////////////////////// -// class template FunctorImpl -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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; -}; - -#endif //LOKI_DISABLE_TYPELIST_MACROS - -//////////////////////////////////////////////////////////////////////////////// -// class template FunctorHandler -// 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) - - -#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_; - } -#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_; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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) - : pObj_(pObj), pMemFn_(pMemFn) - {} - - 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_; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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") - {} -}; - -#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL if(empty()) throw bad_function_call(); - -#else - -#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL - -#endif - -//////////////////////////////////////////////////////////////////////////////// -/// \class Functor -/// -/// \ingroup FunctorGroup -/// A generalized functor implementation with value semantics -/// -/// \par Macro: LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT -/// Define -/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode -/// 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 -/// static Functor objects. -/// -/// \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 -/// 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) - : spImpl_(new FunctorHandler<Functor, Fun>(fun)) - {} - - 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; - - 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; - } - -#ifdef LOKI_ENABLE_FUNCTION - - bool empty() const - { - return spImpl_.get() == 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); - } -#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 -// -//////////////////////////////////////////////////////////////////////////////// - -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; - - typedef typename TL::Erase<TList, typename TL::TypeAt<TList, 0>::Result> - ::Result - ParmList; - - typedef typename TL::TypeAt<TList, 0>::Result OriginalParm1; - - typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType; - - typedef typename BoundFunctorType::Impl Impl; - -}; - - -template<class T> -struct BinderFirstBoundTypeStorage; - -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; -}; - - -} // 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) - : f_(fun), b_(bound) - {} - - 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_); - } -#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_; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// 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))); -} - -//////////////////////////////////////////////////////////////////////////////// -/// \class Chainer -/// -/// \ingroup FunctorGroup -/// 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) - -#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_); - } -#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, - 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_; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// 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))); -} - -} // namespace Loki - - -#endif // end file guardian - diff --git a/shared/loki/HierarchyGenerators.h b/shared/loki/HierarchyGenerators.h deleted file mode 100644 index 126e0f3e..00000000 --- a/shared/loki/HierarchyGenerators.h +++ /dev/null @@ -1,291 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_HIERARCHYGENERATORS_INC_ -#define LOKI_HIERARCHYGENERATORS_INC_ - -// $Id: HierarchyGenerators.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -#include "Typelist.h" -#include "TypeTraits.h" -#include "EmptyType.h" - -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( disable : 4584 ) -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// class template GenScatterHierarchy -// 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 -//////////////////////////////////////////////////////////////////////////////// - -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 AtomicType, template <class> class Unit> -class GenScatterHierarchy : public Unit<AtomicType> -{ - typedef Unit<AtomicType> LeftBase; - template <typename T> struct Rebind - { - typedef Unit<T> Result; - }; -}; - -template <template <class> class Unit> -class GenScatterHierarchy<NullType, Unit> -{ - template <typename T> struct Rebind - { - 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 -//////////////////////////////////////////////////////////////////////////////// - -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 -//////////////////////////////////////////////////////////////////////////////// - -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) -//////////////////////////////////////////////////////////////////////////////// - -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> -{ - 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, - typename H::LeftBase >::Result LeftBase; - - 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; - } -}; - -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; - - enum - { - 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, - 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); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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, -// 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 -//////////////////////////////////////////////////////////////////////////////// - -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 -// Invocation (TList is a typelist, Unit is a template of two args): -// 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 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 ) -#endif -} // namespace Loki - -#endif // end file guardian - diff --git a/shared/loki/Key.h b/shared/loki/Key.h deleted file mode 100644 index a416d6a9..00000000 --- a/shared/loki/Key.h +++ /dev/null @@ -1,766 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2006 by Guillaume Chatelet -// -// 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 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 -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_KEY_INC_ -#define LOKI_KEY_INC_ - -// $Id: Key.h 771 2006-10-27 18:05:03Z clitte_bbt $ - - -#include <loki/Factory.h> - -namespace Loki -{ - -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); - - -/** - * 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); -}; - - -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) - { - 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) -{ - 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; - } -} - - - -} // namespace Loki - -#endif // end file guardian - diff --git a/shared/loki/LevelMutex.h b/shared/loki/LevelMutex.h deleted file mode 100644 index eb01f44a..00000000 --- a/shared/loki/LevelMutex.h +++ /dev/null @@ -1,1211 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// LevelMutex facility for the Loki Library -// 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 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 warranty. -// -//////////////////////////////////////////////////////////////////////////////// - -// $Id$ - -/// @file LevelMutex.h Defines classes and functions for LevelMutex facility. - -#ifndef LOKI_LEVEL_MUTEX_H_INCLUDED -#define LOKI_LEVEL_MUTEX_H_INCLUDED - - -// ---------------------------------------------------------------------------- - -#include <vector> -#include <assert.h> -#include <time.h> - -#if defined( _MSC_VER ) -#include <Windows.h> -#else -#include <pthread.h> -#endif - -#if !defined(_WIN32) && !defined(_WIN64) -#include <unistd.h> // declares sleep under Linux -#endif - -/** @par thread_local Keyword - The mutexes require compilers to provide thread local storage - meaning each - thread gets its own copy of the data. The next version of C++ will have a - new keyword, thread_local for that purpose. Some existing compilers already - provide thread local storage using different syntax, so these lines use - thread_local to mimic that syntax. If your compiler provides thread local - storage but using different syntax besides "thread_local", you may want to - modify these lines. If your compiler does not support thread local storage, - 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 -#endif - -#if defined( DEBUG ) || defined( _DEBUG ) -#define LOKI_MUTEX_DEBUG_CODE( x ) x -#else -#define LOKI_MUTEX_DEBUG_CODE( x ) -#endif - - -namespace Loki -{ - - -// ---------------------------------------------------------------------------- - -class MutexErrors -{ -public: - - /// @enum Type Possible error conditions detected by LevelMutex functions. - enum Type - { - Success = 0, ///< Operation occurred correctly. - NoProblem, ///< Pre-lock and pre-unlock checks passed. - WrongLevel, ///< All mutexes in container must have same level. - LevelTooLow, ///< Trying to unlock a mutex lower than current level. - LevelTooHigh, ///< Trying to lock a mutex higher than current level. - TryFailed, ///< TryLock call failed to lock mutex. - NullMutexPointer, ///< Container has a NULL pointer in it. - DuplicateMutex, ///< Container must have unique pointers - no duplicates. - EmptyContainer, ///< Container must have at least 1 pointer in it. - AlreadyLocked, ///< TryLock call failed because mutex already locked. - WasntLocked, ///< Unlock failed because mutex was not even locked. - NotRecentLock, ///< Mutex in container was not recently locked by this thread. - NotLockedByThread, ///< Can't unlock a mutex not locked by this thread. - MultiUnlockFailed, ///< MultiUnlock can't unlock at least 1 mutex in container. - TimedOut, ///< Wait time elapsed without locking mutex. - TooMuchRecursion, ///< Tried to relock a PThread mutex which is not re-entrant. - NotInitialized, ///< Tried to lock a PThread mutex which did not get setup. - AlreadyInitialized, ///< PThread mutex initialized before ctor called. - InvalidAttribute, ///< PThread mutex improperly initialized. - InvalidAddress, ///< Bad pointer used to initialize a PThread mutex. - ExceptionThrown, ///< Exception caught in mutex operation. - MayDeadlock, ///< Locking this mutex may cause a deadlock. - OtherError ///< Unknown error occurred. - }; -}; - -// ---------------------------------------------------------------------------- - -/** @class LevelMutexInfo - This monolithic base class stores common info for a template class used to - control mutexes. The template class, LevelMutex, is policy-based class. - - @par Implementation - Each thread has a list of mutexes it locked. When a mutex first gets locked, it - gets added to the head of the list. If locked again, LevelMutex merely increments - a count. When unlocked, the count gets decremented until it reaches zero, and - then it gets removed from the list. Each mutex has a pointer to the mutex most - recently locked by the current thread. The current level of a thread is always - the level of the most recently locked mutex, or UnlockedLevel if the thread does - not have any mutexes locked now. A mutex is considered "recently" locked if it is at - the head of the list, or the same level as the current mutex and also locked by the - current thread. - - @par Class Invariants - This class maintains invariants for each LevelMutexInfo so that no function - calls corrupt a mutex. Each function makes a call to IsValid at the start so - that LevelMutex knows it acts on valid internal data. Many functions call - IsValid again when they return to insure the function did not leave any data in - an invalid state. The exit call to IsValid occurs through a tiny helper class - called Checker to insure all data remain valid even when exceptions occur. - Another helper class, MutexUndoer, unlocks mutexes in a container if an - exception occurs during calls to MultiLock. - - @par Error Results - Many functions return an enum value to indicate an error status. Many enum values - indicate errors detected within LevelMutex, but some indicate errors found in policy - classes, SpinLevelMutex and SleepLevelMutex. - */ - -class LevelMutexInfo -{ -public: - - /** Level for thread that has not locked any mutex. Maximum possible level - for a mutex is UnlockedLevel-1; No mutex may have a level of UnlockedLevel. - */ - static const unsigned int UnlockedLevel = 0xFFFFFFFF; - - /// Container for locking multiple mutexes at once. - typedef ::std::vector< volatile LevelMutexInfo* > MutexContainer; - typedef MutexContainer::iterator LevelMutexContainerIter; - typedef MutexContainer::const_iterator LevelMutexContainerCIter; - typedef MutexContainer::reverse_iterator LevelMutexContainerRIter; - typedef MutexContainer::const_reverse_iterator LevelMutexContainerCRIter; - - /** Locks several mutexes at once. Requires O(m + n*n) actions where m is the - number of mutexes currently locked by the thread and n is the number of mutexes - in the container. This provides strong exception safety. If an exception occurs, - any mutexes that were locked during this call will get unlocked. - @param mutexes Container of pointers to mutexes. Container must have at - least 1 mutex, all mutexes must have the same level, no NULL pointers, and all - mutexes must not exceed the thread's current level. This sorts the container - by address order. - @return Enum value indicating success or error. - */ - 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 - in the container, and t is the wait time for each mutex. This provides strong - exception safety. If an exception occurs, any mutexes that were locked during - this call will ge unlocked. - @param mutexes Container of pointers to mutexes. Container must have at - least 1 mutex, all mutexes must have the same level, no NULL pointers, and all - mutexes must not exceed the thread's current level. This sorts the container - by address order. - @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 ); - - /** 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 - occurs when unlocking one mutex, other mutexes in the container get unlocked anyway. - @param mutexes Container of pointers to mutexes. Container must have at least 1 - mutex, all mutexes must have the same level, no NULL pointers, and all mutexes must - 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 ); - - /** 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 ); - - /// Returns the level of this mutex. - inline unsigned int GetLevel( void ) const volatile { return m_level; } - - /// Returns true if this mutex was locked at least once. - inline bool IsLocked( void ) const volatile { return ( 0 < m_count ); } - - /// Returns count of how many times this mutex got locked. - 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 - { - return m_previous; - } - - /** Tries to lock mutex, and returns immediately if mutex already locked by - another thread. It will return immediately with a value of AlreadyLocked - if the mutex was locked by a different thread. It may throw an exception - or assert when errors occur if the ErrorPolicy class implements that behavior. - @return An error condition if any occurred, else Success. - */ - virtual MutexErrors::Type TryLock( void ) volatile = 0; - - /** Blocking call will attempt to lock mutex and wait until it can lock. - This may throw an exception if the lock failed or an error occurred - if - that is what the error policy specifies. - @return An error condition if any occurred, else Success. - */ - virtual MutexErrors::Type Lock( void ) volatile = 0; - - /** Attempts to lock mutex, but only waits for a limited amount of time - before it gives up. Will return quickly if an error occurs before any - attempt to lock. This may throw an exception if the lock failed or an - error occurred - if that is what the error policy specifies. - @param milliSeconds How long to wait. - @return An error condition if any occurred, else Success. - */ - virtual MutexErrors::Type Lock( unsigned int milliSeconds ) volatile = 0; - - /** Unlocks the mutex, or returns an error condition. This may throw an - exception if the lock failed or an error occurred - if that is what the - error policy specifies. - @return An error condition if any occurred, else Success. - */ - virtual MutexErrors::Type Unlock( void ) volatile = 0; - - /** Returns true if this mutex was locked by current thread, and level is the same - as the current thread's level. Which means this was the most recently locked - mutex, or it was locked along with several others of the same level recently. - */ - bool IsRecentLock( void ) const volatile; - - /** Returns true if this mutex was locked within the last count mutexes. - @param count How many recent mutexes to look through to find this mutex. - */ - bool IsRecentLock( unsigned int count ) const volatile; - - /// Returns true if this was locked by current thread. - bool IsLockedByCurrentThread( void ) const volatile; - - /// Returns true if this was locked by another thread. - bool IsLockedByAnotherThread( void ) const volatile; - -protected: - - /** @class Checker Performs validity check on mutex to insure no class invariants - were violated inside any member function. This class only gets used in debug - builds, and any instance of it gets optimized away in release builds. A checker - is created inside many of member functions so that it's destructor gets called - when the function exits. It determines if any class invariants were violated - during the function call. - */ - class Checker - { - public: - 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; - }; - - /** @class MutexUndoer - Undoes actions by MultiLock if an exception occurs. It keeps track of - which mutexes in a container got locked, and if an exception occurs, then - the destructor unlocks them. If MultiLock succeeds, then it cancels the - undoer so nothing gets unlocked inadvertently. - */ - class MutexUndoer - { - public: - - explicit MutexUndoer( MutexContainer& mutexes ); - ~MutexUndoer( void ); - void SetPlace( LevelMutexContainerIter& here ); - void Cancel( void ); - - private: - - MutexUndoer( void ); - MutexUndoer( const MutexUndoer& ); - MutexUndoer& operator = ( const MutexUndoer& ); - - MutexContainer& m_mutexes; - LevelMutexContainerIter m_here; - }; - - /** Returns true if linked-list of locked mutexes in this thread is valid. - Which means the list has no loops, and each previous mutex on the list has a - higher or same level as the current mutex. Called by IsValid. - */ - static bool IsValidList( void ); - - /** This is the only available constructor, and it forces any derived class to set - a level for each mutex. - */ - explicit LevelMutexInfo( unsigned int level ); - - /// The destructor only gets called by the derived class. - virtual ~LevelMutexInfo( void ); - - MutexErrors::Type PreLockCheck( bool forTryLock ) volatile; - - MutexErrors::Type PreUnlockCheck( void ) volatile; - - /** This gets called after each call to DoLock and DoTryLock to make sure the data - members in this object get set correctly. - */ - void PostLock( void ) volatile; - - /// Gets called just before an attempt to unlock a mutex. - void PreUnlock( void ) volatile; - - /// Called to relock a mutex already locked by the current thread. - void IncrementCount( void ) volatile; - - /// Called to unlock a mutex locked multiple times by the current thread. - void DecrementCount( void ) volatile; - - /** Returns true if no class invariant broken, otherwise asserts. This function - only gets called in debug builds. - */ - bool IsValid( void ) const volatile; - -private: - - /// Copy constructor is not implemented. - LevelMutexInfo( const LevelMutexInfo& ); - /// Copy-assignment operator is not implemented. - LevelMutexInfo& operator = ( const LevelMutexInfo& ); - - /** Called only by MultiLock & MultiUnlock to pass a result through an - error checking policy. - @param result What error condition to check. - @return Result or assertion or an exception - depending on error policy. - */ - virtual MutexErrors::Type DoErrorCheck( MutexErrors::Type result ) const volatile = 0; - - /// Called only by MultiLock to Lock each particular mutex within a container. - virtual MutexErrors::Type LockThis( void ) volatile = 0; - - /** Called only by MultiLock to lock each particular mutex within a container. - @param milliSeconds How much time to wait before giving up on locking a mutex. - */ - virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile = 0; - - /// 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; - - /// Level of this mutex. - const unsigned int m_level; - - /// How many times this mutex got locked. - unsigned int m_count; - - /// Pointer to mutex locked before this one. - volatile LevelMutexInfo* m_previous; - -}; - -// ---------------------------------------------------------------------------- - -/** @class ThrowOnAnyMutexError - Implements the ErrorPolicy for LevelMutex and throws an exception for any - error condition. Only allows MutexErrors::Success and MutexErrors::NoProblem - to get through. Useful for release builds. - */ -class ThrowOnAnyMutexError -{ -public: - static MutexErrors::Type CheckError( MutexErrors::Type error, - unsigned int level ); -}; - -// ---------------------------------------------------------------------------- - -/** @class ThrowOnBadDesignMutexError - Implements the ErrorPolicy for LevelMutex and throws an exception if the error - indicates the programmer did not levelize the calls to mutexes. Otherwise - returns the error result. Useful for release builds. - */ -class ThrowOnBadDesignMutexError -{ -public: - static MutexErrors::Type CheckError( MutexErrors::Type error, - unsigned int level ); -}; - -// ---------------------------------------------------------------------------- - -/** @class AssertAnyMutexError - Implements the ErrorPolicy for LevelMutex and asserts for any error condition. - Only allows MutexErrors::Success and MutexErrors::NoProblem to get through. - Useful for testing mutexes in debug builds. - */ -class AssertAnyMutexError -{ -public: - static inline MutexErrors::Type CheckError( MutexErrors::Type error, - unsigned int level ) - { - (void)level; - assert( ( error == MutexErrors::Success ) - || ( error == MutexErrors::NoProblem ) ); - return error; - } -}; - -// ---------------------------------------------------------------------------- - -/** @class AssertBadDesignMutexError - Implements the ErrorPolicy for LevelMutex and asserts if the error - indicates the programmer did not levelize the calls to mutexes. Otherwise - returns the error result. Useful for testing mutexes in debug builds. - */ -class AssertBadDesignMutexError -{ -public: - static inline MutexErrors::Type CheckError( MutexErrors::Type error, - unsigned int level ) - { - (void)level; - assert( ( error != MutexErrors::LevelTooHigh ) - && ( error != MutexErrors::LevelTooLow ) ); - return error; - } -}; - -// ---------------------------------------------------------------------------- - -/** @class JustReturnMutexError - Implements the ErrorPolicy for LevelMutex and does nothing no matter how bad - the error condition. Only recommended use is for automated unit-testing of - mutex policies. - */ -class JustReturnMutexError -{ -public: - static inline MutexErrors::Type CheckError( MutexErrors::Type error, - unsigned int level ) - { - (void)level; - return error; - } -}; - -// ---------------------------------------------------------------------------- - -/** @class NoMutexWait - Implements the WaitPolicy for LevelMutex. Does nothing at all so it turns - all wait loops into spin loops. Useful for low-level mutexes. - */ -class NoMutexWait -{ -public: - static inline void Wait( void ) {} -}; - -// ---------------------------------------------------------------------------- - -/** @class MutexSleepWaits - Implements the WaitPolicy for LevelMutex. Sleeps for a moment so thread won't - consume idle CPU cycles. Useful for high-level mutexes. - */ -class MutexSleepWaits -{ -public: - static void Wait( void ); - static unsigned int sleepTime; -}; - -// ---------------------------------------------------------------------------- - -/** @class SpinLevelMutex - Implements a spin-loop to wait for the mutex to unlock. Since this class makes - the thread wait in a tight spin-loop, it can cause the thread to remain busy - while waiting and thus consume CPU cycles. For that reason, this mutex is best - used only for very low-level resources - especially resources which do not - require much CPU time to exercise. Rule of thumb: Use this only if all actions - on the resource consume a very small number of CPU cycles. Otherwise, use the - SleepLevelMutex instead. - */ -class SpinLevelMutex -{ -public: - - /// Constructs a spin-level mutex. - explicit SpinLevelMutex( unsigned int level ); - - /// Destructs the mutex. - virtual ~SpinLevelMutex( void ); - - virtual MutexErrors::Type Lock( void ) volatile; - - virtual MutexErrors::Type TryLock( void ) volatile; - - virtual MutexErrors::Type Unlock( void ) volatile; - - inline unsigned int GetLevel( void ) const volatile { return m_level; } - -private: - - /// Copy constructor is not implemented. - SpinLevelMutex( const SpinLevelMutex& ); - /// Copy-assignment operator is not implemented. - 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 - -#elif ( __GNUC__ ) - /// The actual mutex. - pthread_mutex_t m_mutex; - -#else -#error "Check if any mutex libraries are compatible with your compiler." -#endif - - /// Keep a copy of the mutex level around for error reporting. - const unsigned int m_level; - -}; // end class SpinLevelMutex - -// ---------------------------------------------------------------------------- - -/** @class SleepLevelMutex - 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 - 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 - SleepLevelMutex's should have higher levels than all your SpinLevelMutex's. - - @par Dependence on SpinLevelMutex - This utilizes SpinLevelMutex so it does not have to re-implement the DoTryLock - and DoUnlock functions the same way. All it really needs is a DoLock function - and the amount of time it should sleep if an attempt to lock a function fails. - */ -class SleepLevelMutex : public SpinLevelMutex -{ -public: - - /** Constructs a levelized mutex that puts threads to sleep while they wait - for another thread to unlock the mutex. - @param level Level of this mutex. - */ - explicit SleepLevelMutex( unsigned int level ); - - SleepLevelMutex( unsigned int level, unsigned int sleepTime ); - - /// Destructs the mutex. - virtual ~SleepLevelMutex( void ); - - inline unsigned int GetSleepTime( void ) const volatile { return m_sleepTime; } - - inline void SetSleepTime( unsigned int sleepTime ) volatile - { - if ( 0 != sleepTime ) - m_sleepTime = sleepTime; - } - -#if defined( _MSC_VER ) - inline bool GetWakable( void ) const volatile { return m_wakable; } - inline void SetWakable( bool wakable ) volatile { m_wakable = wakable; } -#endif - - /** Attempts to lock a mutex, and if it fails, then sleeps for a while - before attempting again. - */ - virtual MutexErrors::Type Lock( void ) volatile; - -private: - - /// Default constructor is not implemented. - SleepLevelMutex( void ); - /// Copy constructor is not implemented. - SleepLevelMutex( const SleepLevelMutex& ); - /// Copy-assignment operator is not implemented. - 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 -#endif - - /// How many milli-seconds to sleep before trying to lock mutex again. - unsigned int m_sleepTime; - -}; // end class SleepLevelMutex - -// ---------------------------------------------------------------------------- - -/** @class LevelMutex - Levelized mutex class prevents deadlocks by requiring programs to lock mutexes in - the same order, and unlock them in reverse order. This is accomplished by forcing - each mutex to have a level and forcing code to lock mutexes with higher levels - before locking mutexes at lower levels. If you want to lock several mutexes, they - must be locked in decreasing order by level, or if they are all of the same level, - then locked by LevelMutex::MultiLock. - - @par Features - - Immune: Very unlikely to deadlock since all mutexes are locked in the same - order and unlocked in reverse order. - - Scalable: Can handle any number of mutexes. - - Efficient: Many operations occur in constant time, and most operations require - no more than O(m) steps. - - Exception safe: All operations provide strong safety or don't throw. - - Extendable: Can work with existing mutexes through policy-based design. - - Easily Extended: Derived classes only need to implement 5 functions and a mutex - to get all the features of this class. - - Re-Entrant: Allows for re-entrancy even if mutexes in policy classes don't. - - Cost-Free: No resource allocations occur in LevelMutex - although user-defined - policy classes may allocate resources. - - Compact: Each LevelMutex object is small. - - Portable: As long as your compiler and libraries can meet the requirements. - - Robust: Maintains data integrity even if exceptions occur in policy classes. - - Affording: Several functions provide information about a mutex which allows - client code to easily choose correct actions. - - @par Requirements - - Your compiler must allow for thread-specific data. - - You must have a threading or mutex library. - - @par Policy-Based Design - This class hosts 3 policies and a default level. The policy-based design allows - users to write their own policies to extend the behaviors of LevelMutex. The - paragraphs below say how to design a class for each policy. - - MutexPolicy The mutex policy class. - - defaultLevel A level for existing client code that calls a default constructor. - - ErrorPolicy How the mutex should handle error conditions. - - WaitPolicy Whether a thread should wait, and how long in some internal loops. - - @par MutexPolicy - A policy class that wraps a low-level mutex. Loki provides two policy classes - for the actual mutex (SpinLevelMutex and SleepLevelMutex), both of which wrap - either pthreads or the Windows CRITICAL_SECTION. If you want to use a mutex - mechanism besides one of those, then all you have to do is provide a class - which wraps the mutex and implements these functions. - explicit SpinLevelMutex( unsigned int level ); - virtual ~SpinLevelMutex( void ); - virtual MutexErrors::Type Lock( void ) volatile; - virtual MutexErrors::Type TryLock( void ) volatile; - virtual MutexErrors::Type Unlock( void ) volatile; - Indeed, since the base class does most of the work, and provides all the interace - and functionality to client classes, a derived class has very few requirements. - It only needs to implement a single constructor, the destructor, some virtual - functions, and whatever data members it requires. You don't actually need to - declare those functions as virtual if the policy class is not a base or child - class. In the parlance of design patterns, LevelMutex is a Template, and the - MutexPolicy is a Strategy. - - @par DefaultLevel - The template class requires a default level to use inside the default constructor. - Some existing code calls instantiates mutexes with a default constructor, so the - mutex must know what level to use there. Please do not use zero or UnlockedLevel - as the default level. - - @par ErrorPolicy - This policy specifies how to handle error conditions. The mutexes can return - errors, assert, or throw exceptions. I recommend that debug code use asserts, - release code use exceptions, and unit-testing code just return errors. The - error policy class only needs to implement one function: - static MutexErrors::Type CheckError( MutexErrors::Type error, unsigned int level ); - - @par WaitPolicy - This states whether the mutex should wait within some tight internal loops, - how the waiting is done, and for how long. A wait policy class could sleep, - do nothing, check if other objects need attention, or check if the program - received events or notices from the operating system. It only needs to - implement one function: - static void Wait( void ); - - @par Per-Function Usage - If you implement a function with a static local mutex, then you have to insure - the function is not called from a lower level via call-backs, virtual functions in - interface classes. If the function does get called from a lower level, you are - setting up a potential deadlock. LevelMutex will detect that by checking the - current level and the local mutex's level, so it will refuse to lock the local mutex. - - @par Per-Object Usage - If you use a mutex as a data member of an object to protect that object, then I - recommend specifying which functions are volatile and which are not, and then only - use the mutex within the volatile functions. You may also want to provide accessor - functions so that client code can lock and unlock the mutex either to allow for - calling multiple operations without having to lock and unlock before and after each - operation, or so they can lock it along with several other objects at the same - level. - - @par Per-Class Usage - If you make a static data member within a class, you can use that to lock any - resources shared by those objects, or to require threads to act on only one object - at a time. You may also want to provide static accessor functions so that client - code can lock several other resources at the same level. - */ - -template -< -class MutexPolicy, - unsigned int DefaultLevel, - class ErrorPolicy = ::Loki::ThrowOnBadDesignMutexError, - class WaitPolicy = ::Loki::NoMutexWait - > -class LevelMutex : public LevelMutexInfo -{ -public: - - typedef ErrorPolicy EP; - typedef WaitPolicy WP; - typedef MutexPolicy MP; - - /** This constructor allows callers to replace the default level with another - value. It also acts as the default constructor for existing code which uses - default construction for mutexes. This is the only time the DefaultLevel - template parameter gets used. - */ - explicit LevelMutex( unsigned int level = DefaultLevel ) : - LevelMutexInfo( level ), - m_mutex( level ) - { - assert( IsValid() ); - } - - /// The destructor. - ~LevelMutex( void ) - { - assert( IsValid() ); - } - - /** These functions allow callers to access the mutex in case they need to - modify specific values in the MutexPolicy (e.g. - sleep time, functors to - call as tasks, etc...) There is one function for every combination of - 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; } - - virtual MutexErrors::Type TryLock( void ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - MutexErrors::Type result = LevelMutexInfo::PreLockCheck( true ); - if ( MutexErrors::Success == result ) - return MutexErrors::Success; - else if ( MutexErrors::AlreadyLocked == result ) - return result; - else if ( MutexErrors::NoProblem != result ) - return EP::CheckError( result, GetLevel() ); - - assert( 0 == LevelMutexInfo::GetLockCount() ); - result = m_mutex.TryLock(); - if ( MutexErrors::Success != result ) - return EP::CheckError( result, GetLevel() ); - LevelMutexInfo::PostLock(); - - return MutexErrors::Success; - } - - virtual MutexErrors::Type Lock( void ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); - if ( MutexErrors::Success == result ) - return MutexErrors::Success; - else if ( MutexErrors::NoProblem != result ) - return EP::CheckError( result, GetLevel() ); - - assert( !LevelMutexInfo::IsLockedByCurrentThread() ); - result = m_mutex.Lock(); - if ( MutexErrors::Success != result ) - return EP::CheckError( result, GetLevel() ); - PostLock(); - - return MutexErrors::Success; - } - - virtual MutexErrors::Type Lock( unsigned int milliSeconds ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); - if ( MutexErrors::Success == result ) - return MutexErrors::Success; - else if ( MutexErrors::NoProblem != result ) - return EP::CheckError( result, GetLevel() ); - - assert( !LevelMutexInfo::IsLockedByCurrentThread() ); - clock_t timeOut = clock() + milliSeconds; - while ( clock() < timeOut ) - { - WP::Wait(); - result = m_mutex.TryLock(); - switch ( result ) - { - case MutexErrors::Success: - { - PostLock(); - return MutexErrors::Success; - } - case MutexErrors::AlreadyLocked: - return MutexErrors::AlreadyLocked; - case MutexErrors::TryFailed: - break; - default: - return EP::CheckError( result, GetLevel() ); - } - } - - return MutexErrors::TimedOut; - } - - virtual MutexErrors::Type Unlock( void ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - MutexErrors::Type result = LevelMutexInfo::PreUnlockCheck(); - if ( MutexErrors::Success == result ) - return MutexErrors::Success; - else if ( MutexErrors::NoProblem != result ) - return EP::CheckError( result, GetLevel() ); - - LevelMutexInfo::PreUnlock(); - result = MutexErrors::OtherError; - try - { - result = m_mutex.Unlock(); - if ( MutexErrors::Success != result ) - PostLock(); - } - catch ( ... ) - { - PostLock(); - result = MutexErrors::ExceptionThrown; - } - - return result; - } - -private: - - /// Copy constructor is not implemented since mutexes don't get copied. - LevelMutex( const LevelMutex& ); - /// Copy-assignment operator is not implemented since mutexes don't get copied. - LevelMutex& operator = ( const LevelMutex& ); - - virtual MutexErrors::Type DoErrorCheck( MutexErrors::Type result ) const volatile - { - return EP::CheckError( result, GetLevel() ); - } - - /** Called only by MultiLock to lock each particular mutex within a container. - This does not do pre-lock error checking since MultiLock does that. Since - this skips the error checking, that means that callers of LevelMutex should - not call this function directly, and so this will not be publicly available. - @return Error status indicating success or reason for failure. - */ - virtual MutexErrors::Type LockThis( void ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - assert( this != LevelMutexInfo::GetCurrentMutex() ); - - const MutexErrors::Type result = m_mutex.Lock(); - if ( MutexErrors::Success != result ) - return result; - PostLock(); - - return MutexErrors::Success; - } - - /** Called only by MultiLock to lock each particular mutex within a container. - This does not do pre-lock error checking since MultiLock does that. Since - this skips the error checking, callers of LevelMutex should not call this - function directly, and so this will not be publicly available. - @param milliSeconds How much time to wait before giving up on locking a mutex. - @return Error status indicating success or reason for failure. - */ - virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile - { - assert( IsValid() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - clock_t timeOut = clock() + milliSeconds; - while ( clock() < timeOut ) - { - WP::Wait(); - const bool locked = ( MutexErrors::Success == m_mutex.TryLock() ); - if ( locked ) - { - PostLock(); - return MutexErrors::Success; - } - } - - return MutexErrors::TimedOut; - } - - /** Called only by MultiUnlock to unlock each mutex within a container. - This does not do pre-unlock error checking since MultiLock does that. Since - this skips the error checking, callers of LevelMutex should not call this - function directly, and so this will not be publicly available. - @return Error status indicating success or reason for failure. - */ - virtual MutexErrors::Type UnlockThis( void ) volatile - { - assert( IsValid() ); - assert( NULL != LevelMutexInfo::GetCurrentMutex() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) - - if ( 1 < LevelMutexInfo::GetLockCount() ) - { - LevelMutexInfo::DecrementCount(); - return MutexErrors::Success; - } - - LevelMutexInfo::PreUnlock(); - MutexErrors::Type result = m_mutex.Unlock(); - - return result; - } - - /// An instance of an unleveled mutex wrapped to match LevelMutex's needs. - MutexPolicy m_mutex; - -}; // end class LevelMutex - -// ---------------------------------------------------------------------------- - -/** Returns level of most recently locked mutex by this thread, or UnlockedLevel - if no mutexes are locked. Runs in constant time, and never throws exceptions. - */ -unsigned int GetCurrentThreadsLevel( void ); - -/** Returns count of how mutexes the current thread locked. Requires O(m) - actions where m is the number of mutexes in the thread. Never throws exceptions. - */ -unsigned int CountMutexesInCurrentThread( void ); - -/** Returns count of how mutexes the current thread locked. The lock count - exceeds the number of mutexes locked by current thread if any mutex got locked - more than once. Requires O(m) actions where m is the number of mutexes in the - thread. Never throws exceptions. - */ -unsigned int CountLocksInCurrentThread( void ); - -/** Returns count of mutexes locked by current thread which have the same level - as GetCurrentThreadsLevel. Requires O(m) actions where m is the number of - mutexes in the thread at current level. Never throws exceptions. - */ -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 ); - -// ---------------------------------------------------------------------------- - -/** @class MutexException - Exception class used to throw error statuses about LevelMutex's up to code that - can respond to mutex problems. This class exists because it conveys more info - about the error condition than just ::std::exception. - */ -class MutexException : public ::std::exception -{ -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 ); - - /// Copy constructor performs a member-by-member copy of an exception. - MutexException( const MutexException& that ) throw (); - - /// Copy-assignment operator performs a member-by-member copy of an exception. - 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(); - - /// Returns level of mutex(es) used when problem occurred. - unsigned int GetLevel( void ) const { return m_level; } - - /// Returns an error status for why operation failed. - MutexErrors::Type GetReason( void ) const { return m_reason; } - -private: - - /// Default constructor is not implemented. - MutexException( void ) throw (); - - /// Simple message about operation that failed. - const char* m_message; - /// Level of mutex(es) used when problem occurred. - unsigned int m_level; - /// Error status for why operation failed. - MutexErrors::Type m_reason; - -}; // end class MutexException - -// ---------------------------------------------------------------------------- - -/** @class MutexLocker - You can place an instance of this as a local variable inside a function to lock - a single mutex. It will lock the mutex if no error occurs, or throw if one - does happen. When the function ends, the destructor will determine if it needs - to unlock the mutex. This RAII technique insures the mutex gets unlocked even - when exceptions occur. - */ -class MutexLocker -{ -public: - - /** Creates an object to lock an unlock a mutex for a function. This - will throw if an attempt to lock the mutex fails. - @param mutex Reference to the mutex. - @param lock True if function wants to lock the mutex as this gets - constructed. - */ - 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 - locked. This will throw if an attempt to lock the mutex fails. - @param mutex Reference to the mutex. - @param milliSeconds Amount of time to wait for another thread to unlock - the mutex. - @param lock True if function wants to lock the mutex as this gets - constructed. - */ - MutexLocker( volatile LevelMutexInfo& mutex, unsigned int milliSeconds, - bool lock = true ); - - /// Destructs the locker, and determines if it needs to unlock the mutex. - ~MutexLocker( void ); - - /** You can call this to lock (or relock) a mutex. In theory, you can lock - and unlock a mutex several times within a function in order to give other - threads access to a resource while this function does not need it. - @return True if mutex is locked by this, else false if not locked. - */ - bool Lock( void ); - - /** You can call this to unlock a mutex before the destructor does it. - By unlocking the mutexes before returning, the function can do other - operations without making other threads wait too long. - @return True if unlocked by this, else false if not unlocked by this. - (Which is not the same as whether the mutex itself is locked or not by - another thread.) - */ - bool Unlock( void ); - - /// 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; } - -private: - - /// Default constructor is not implemented. - MutexLocker( void ); - /// Copy constructor is not implemented. - MutexLocker( const MutexLocker& ); - /// Copy-assignment operator is not implemented. - MutexLocker& operator = ( const MutexLocker& ); - - /// True if mutex got locked. - bool m_locked; - - /// Reference to mutex. - volatile LevelMutexInfo& m_mutex; -}; - -// ---------------------------------------------------------------------------- - -/** @class MultiMutexLocker - You can place an instance of this as a local variable inside a function to lock - a collection of mutexes. It locks them if no error occurs, or throws an - exception if one does happen. When the function ends, the destructor determines - if it needs to unlock the mutexes. This RAII technique insures the mutexes get - unlocked even when exceptions occur. You will also have to construct a - MutexContainer as a local object within the same function. - */ -class MultiMutexLocker -{ -public: - - /** Creates an object to lock and unlock a collection of mutexes for a function. - This will throw if an attempt to lock any mutex fails. If an exception occurs, - it unlocks mutexes it previously locked. - @param mutex Reference to a collection of mutexes. - @param lock True if function wants to lock the mutex as this gets - constructed. - */ - 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 - that is locked. This will throw if an attempt to lock any mutex fails. If an - exception occurs, it unlocks mutexes it previously locked. - @param mutexes Reference to a collection of mutexes. - @param milliSeconds Amount of time to wait for another thread to unlock - the mutex. - @param lock True if function wants to lock the mutexes as this gets - constructed. - */ - MultiMutexLocker( LevelMutexInfo::MutexContainer& mutexes, - unsigned int milliSeconds, bool lock = true ); - - /// Destructs the locker, and determines if it needs to unlock the mutexes. - ~MultiMutexLocker( void ); - - /** You can call this to lock (or relock) the mutexes. In theory, you can lock - and unlock mutexes several times within a function in order to give other - threads access to resources while this function does not need them. - @return True if mutex is locked by this, else false if not locked. - */ - bool Lock( void ); - - /** You can call this to unlock the mutexes before the destructor does it. - By unlocking the mutexes before returning, the function can do other - operations without making other threads wait too long. - @return True if unlocked by this, else false if not unlocked by this. - (Which is not the same as whether the mutex itself is locked or not by - another thread.) - */ - bool Unlock( void ); - - /// 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; } - -private: - - /// Default constructor is not implemented. - MultiMutexLocker( void ); - /// Copy constructor is not implemented. - MultiMutexLocker( const MultiMutexLocker& ); - /// Copy-assignment operator is not implemented. - MultiMutexLocker& operator = ( const MultiMutexLocker& ); - - /// True if mutexes got locked. - bool m_locked; - - /// Reference to external container of mutexes; - LevelMutexInfo::MutexContainer& m_mutexes; -}; - -// ---------------------------------------------------------------------------- - -} // end namespace Loki - -#endif // end file guardian diff --git a/shared/loki/LockingPtr.h b/shared/loki/LockingPtr.h deleted file mode 100644 index 5482f075..00000000 --- a/shared/loki/LockingPtr.h +++ /dev/null @@ -1,110 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code is from the article: -// "Generic<Programming>: volatile — Multithreaded Programmer’s Best Friend -// Volatile-Correctness or How to Have Your Compiler Detect Race Conditions -// 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 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 warranty. -// Prepared for Loki library by Richard Sposato -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_LOCKING_PTR_INC_ -#define LOKI_LOCKING_PTR_INC_ - -// $Id: LockingPtr.h 840 2008-03-19 19:44:38Z rich_sposato $ - - -#include <loki/ConstPolicy.h> -#include <loki/Threads.h> - - -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. - */ -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 - */ - 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 - -} // namespace Loki - -#endif // end file guardian - diff --git a/shared/loki/LokiExport.h b/shared/loki/LokiExport.h deleted file mode 100644 index eb02516b..00000000 --- a/shared/loki/LokiExport.h +++ /dev/null @@ -1,69 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_LOKIEXPORT_INC_ -#define LOKI_LOKIEXPORT_INC_ - -// $Id: LokiExport.h 748 2006-10-17 19:49:08Z syntheticpp $ - - -#ifdef __GNUC__ - -#ifdef _HAVE_GCC_VISIBILITY -#define LOKI_EXPORT_SPEC __attribute__ ((visibility("default"))) -#define LOKI_IMPORT_SPEC -#else -#define LOKI_EXPORT_SPEC -#define LOKI_IMPORT_SPEC -#endif - -#else - -#ifdef _WIN32 -#define LOKI_EXPORT_SPEC __declspec(dllexport) -#define LOKI_IMPORT_SPEC __declspec(dllimport) -#else -#define LOKI_EXPORT_SPEC -#define LOKI_IMPORT_SPEC -#endif - -#endif - - -#if (defined(LOKI_MAKE_DLL) && defined(LOKI_DLL)) || \ - (defined(LOKI_MAKE_DLL) && defined(LOKI_STATIC)) || \ - (defined(LOKI_DLL) && defined(LOKI_STATIC)) -#error export macro error: you could not build AND use the library -#endif - -#ifdef LOKI_MAKE_DLL -#define LOKI_EXPORT LOKI_EXPORT_SPEC -#endif - -#ifdef LOKI_DLL -#define LOKI_EXPORT LOKI_IMPORT_SPEC -#endif - -#ifdef LOKI_STATIC -#define LOKI_EXPORT -#endif - -#if !defined(LOKI_EXPORT) && !defined(EXPLICIT_EXPORT) -#define LOKI_EXPORT -#endif - -#ifndef LOKI_EXPORT -#error export macro error: LOKI_EXPORT was not defined, disable EXPLICIT_EXPORT or define a export specification -#endif - - -#endif // end file guardian - diff --git a/shared/loki/LokiTypeInfo.h b/shared/loki/LokiTypeInfo.h deleted file mode 100644 index ecb657d4..00000000 --- a/shared/loki/LokiTypeInfo.h +++ /dev/null @@ -1,103 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_LOKITYPEINFO_INC_ -#define LOKI_LOKITYPEINFO_INC_ - -// $Id: LokiTypeInfo.h 748 2006-10-17 19:49:08Z syntheticpp $ - - -#include <typeinfo> -#include <cassert> -#include "Typelist.h" - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class TypeInfo -// 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_; -}; - -// Implementation - -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(); -} - -// 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); } -} - -#endif // end file guardian diff --git a/shared/loki/MultiMethods.h b/shared/loki/MultiMethods.h deleted file mode 100644 index ec5b7788..00000000 --- a/shared/loki/MultiMethods.h +++ /dev/null @@ -1,415 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_MULTIMETHODS_INC_ -#define LOKI_MULTIMETHODS_INC_ - -// $Id: MultiMethods.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -#include "Typelist.h" -#include "LokiTypeInfo.h" -#include "Functor.h" -#include "AssocVector.h" - -//////////////////////////////////////////////////////////////////////////////// -// IMPORTANT NOTE: -// The double dispatchers implemented below differ from the excerpts shown in -// the book - they are simpler while respecting the same interface. -//////////////////////////////////////////////////////////////////////////////// - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template InvocationTraits (helper) -// Helps implementing optional symmetry -//////////////////////////////////////////////////////////////////////////////// - -namespace Private -{ -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); - } -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 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()); - } - - 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()); } -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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) -{ - 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()) - { - 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 -{ - static To& Cast(From& obj) - { - return static_cast<To&>(obj); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template DynamicCaster -// Implementation of the CastingPolicy used by FunctorDispatcher -//////////////////////////////////////////////////////////////////////////////// - -template <class To, class From> -struct DynamicCaster -{ - static To& Cast(From& obj) - { - return dynamic_cast<To&>(obj); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Private::FnDispatcherHelper -// Implements trampolines and argument swapping used by FnDispatcher -//////////////////////////////////////////////////////////////////////////////// - -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) - { - return Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); - } - static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs) - { - return Trampoline(lhs, rhs); - } -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// class template FnDispatcher -// Implements an automatic logarithmic double dispatcher for functions -// 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 -{ - 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 - { - 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() - { - 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 -{ -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>()); - } -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// class template FunctorDispatcher -// Implements a logarithmic double dispatcher for functors -// 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; - - 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))); - } - 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>(); - } - - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) - { - return backEnd_.Go(lhs, rhs); - } -}; -} // namespace Loki - - - -#endif // end file guardian - diff --git a/shared/loki/NullType.h b/shared/loki/NullType.h deleted file mode 100644 index 8a4bb008..00000000 --- a/shared/loki/NullType.h +++ /dev/null @@ -1,34 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_NULLTYPE_INC_ -#define LOKI_NULLTYPE_INC_ - -// $Id: NullType.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class NullType -// Used as a placeholder for "no type here" -// Useful as an end marker in typelists -//////////////////////////////////////////////////////////////////////////////// - -class NullType {}; - -} // namespace Loki - - -#endif // end file guardian diff --git a/shared/loki/OrderedStatic.h b/shared/loki/OrderedStatic.h deleted file mode 100644 index f0ff73c3..00000000 --- a/shared/loki/OrderedStatic.h +++ /dev/null @@ -1,225 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_ORDEREDSTATIC_INC_ -#define LOKI_ORDEREDSTATIC_INC_ - -// $Id: OrderedStatic.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -#include <vector> -#include <iostream> - -#include "LokiExport.h" -#include "Singleton.h" -#include "Typelist.h" -#include "Sequence.h" - -// usage: see test/OrderedStatic - -namespace Loki -{ -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*() - { - 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> -{ -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 - - -#endif // end file guardian - diff --git a/shared/loki/Pimpl.h b/shared/loki/Pimpl.h deleted file mode 100644 index 8254e3e2..00000000 --- a/shared/loki/Pimpl.h +++ /dev/null @@ -1,198 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_PIMPL_INC_ -#define LOKI_PIMPL_INC_ - -// $Id: Pimpl.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -/// \defgroup PimplGroup Pimpl - -#ifndef LOKI_INHERITED_PIMPL_NAME -#define LOKI_INHERITED_PIMPL_NAME d -#endif - -#ifndef LOKI_INHERITED_RIMPL_NAME -#define LOKI_INHERITED_RIMPL_NAME d -#endif - -namespace Loki -{ - -////////////////////////////////////////// -/// \class ConstPropPtr -/// -/// \ingroup PimplGroup -/// Simple const propagating smart pointer -/// Is the default smart pointer of Pimpl. -////////////////////////////////////////// - -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() - { - // 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_; -}; - - -template<class T, typename Pointer = ConstPropPtr<T> > -struct PimplOwner -{ - Pimpl<T, Pointer> LOKI_INHERITED_PIMPL_NAME; -}; - - -////////////////////////////////////////// -/// \class ImplOf -/// -/// \ingroup PimplGroup -/// Convenience template for the -/// implementations which Pimpl points to. -////////////////////////////////////////// - -template<class T> -struct ImplOf; - - -////////////////////////////////////////// -/// \class PImplOf -/// -/// \ingroup PimplGroup -/// Convenience template which uses ImplOf -/// as implementation structure -////////////////////////////////////////// - - -template<class T, template<class> class Ptr = ConstPropPtr> -struct PimplOf -{ - typedef T Impl; - - // declare pimpl - typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type; - - // inherit pimpl - typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner; -}; - - -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 deleted file mode 100644 index 3f7ecfef..00000000 --- a/shared/loki/RefToValue.h +++ /dev/null @@ -1,70 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_REFTOVALUE_INC_ -#define LOKI_REFTOVALUE_INC_ - -// $Id: RefToValue.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -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) -{ - return RefToValue<T>(t); -} - -} - - -#endif // end file guardian - diff --git a/shared/loki/Register.h b/shared/loki/Register.h deleted file mode 100644 index 2b549381..00000000 --- a/shared/loki/Register.h +++ /dev/null @@ -1,134 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_REGISTER_INC_ -#define LOKI_REGISTER_INC_ - -// $Id: Register.h 776 2006-11-09 13:12:57Z syntheticpp $ - - -#include "TypeManip.h" -#include "HierarchyGenerators.h" - -/// \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 - : 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 - : 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 -//////////////////////////////////////////////////////////////////////////////// - - -#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 ) \ - \ - struct LOKI_CONCAT(check_,CLASS,_isInList_,LIST) \ - { \ - typedef int LOKI_CONCAT(ERROR_class_,CLASS,_isNotInList_,LIST); \ - }; \ - typedef Loki::Select<Loki::TL::IndexOf<LIST, CLASS>::value == -1, \ - CLASS, \ - LOKI_CONCAT(check_,CLASS,_isInList_,LIST)> \ - ::Result LOKI_CONCAT(CLASS,isInList,LIST,result); \ - typedef LOKI_CONCAT(CLASS,isInList,LIST,result):: \ - LOKI_CONCAT(ERROR_class_,CLASS,_isNotInList_,LIST) \ - LOKI_CONCAT(ERROR_class_,CLASS,_isNotInList__,LIST); - - -} // namespace Loki - - -#endif // end file guardian - diff --git a/shared/loki/SPCachedFactory.h b/shared/loki/SPCachedFactory.h deleted file mode 100644 index e1b8ec8c..00000000 --- a/shared/loki/SPCachedFactory.h +++ /dev/null @@ -1,204 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2006 by Guillaume Chatelet -// -// 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 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 -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// -//////////////////////////////////////////////////////////////////////////////// - -// $Id: SPCachedFactory.h 896 2008-08-08 22:20:05Z syntheticpp $ - -#ifndef SPCACHEDFACTORY_H_ -#define SPCACHEDFACTORY_H_ - -/** - * This file is intented to be used if you want a CachedFactory with - * a SmartPointer encapsulation policy. - * 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. - * - * This file defines FunctionStorage a new SmartPointer storage policy and - * SmartPointer a new CachedFactory encapsulation policy. - */ - -#include <loki/Functor.h> -#include <loki/SmartPtr.h> -#include <loki/CachedFactory.h> - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class FunctionStorage -/// -/// \ingroup SmartPointerStorageGroup -/// \brief Implementation of the StoragePolicy used by SmartPtr. -/// -/// This storage policy is used by SmartPointer CachedFactory's encapsulation -/// policy. It's purpose is to call a Functor instead of deleting the -/// underlying pointee object. You have to set the callback functor by calling -/// SetCallBackFunction(const FunctorType &functor). -/// -/// Unfortunately, the functor argument is not a reference to the SmartPtr but -/// a void *. Making functor argument a reference to the pointer would require -/// the FunctionStorage template to know the full definition of the SmartPtr. -//////////////////////////////////////////////////////////////////////////////// - -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) - { - CallBackSP& SP(*reinterpret_cast<CallBackSP*>(pSP)); - ReleaseObject(SP); - } - virtual void ReleaseObject(ProductReturn& object) = 0; - const typename CallBackSP::FunctorType fun; -}; - -} // namespace Loki - -#endif /*SPCACHEDFACTORY_H_*/ diff --git a/shared/loki/SafeBits.h b/shared/loki/SafeBits.h deleted file mode 100644 index 9e160c50..00000000 --- a/shared/loki/SafeBits.h +++ /dev/null @@ -1,514 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2009 by Fedor Pikus & Rich 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 notice appear in supporting documentation. -// -// The author makes no claims about the suitability of this software for any -// purpose. It is provided "as is" without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// $Id$ - - -#ifndef LOKI_INCLUDED_SAFE_BIT_FIELDS_H -#define LOKI_INCLUDED_SAFE_BIT_FIELDS_H - -#include <cstdlib> -#include <assert.h> -#include <loki/static_check.h> - - -namespace Loki -{ - -/* - ========================================================================================================================================== - SafeBitField - type-safe class for bit fields. - SafeBitConst - type-safe class for bit constants. - SafeBitField is designed to be a [almost] drop-in replacement for integer flags and bit fields where individual bits are set and checked - using symbolic names for flags: - - typedef unsigned long Labels_t; - Labels_t labels; - const Labels_t Label_A = 0x00000001; - const Labels_t Label_B = 0x00000002; - ... - labels |= Label_B; - if ( labels & Label_A ) { ... } - - Such code offers no protection against mismatching bit constants and bit fields: - - typedef unsigned long Kinds_t; - Kinds_t kinds; - const Kinds_t Kind_A = 0x00000004; - ... - if ( kinds & Label_A ) { ... } // Error but compiles - - SafeBitField is a drop-in replacement which generates a unique type for each bit field. Bit fields of different types cannot be applied - to each other: - - LOKI_BIT_FIELD( unsigned long ) Labels_t; - Labels_t labels; - LOKI_BIT_CONST( Labels_t, Label_A, 1 ); // 0x0001 - 1st bit is set - LOKI_BIT_CONST( Labels_t, Label_B, 2 ); // 0x0002 - 1st bit is set - ... - LOKI_BIT_FIELD( unsigned long ) Kinds_t; - Kinds_t kinds; - LOKI_BIT_CONST( Kinds_t, Kind_A, 3 ); // 0x0004 - 1st bit is set - ... - if ( kinds & Label_A ) { ... } // Does not compile - - Several other kinds of bit field misuse are caught by safe bit fields: - - if ( kinds & Kind_A == 0 ) { ... } - if ( kinds && Kind_A ) { ... } - - There are few cases where drop-in replacement does not work: - - 1. Operations involving bit fields and unnamed integers. Usually the integer in question is 0: - - Labels_t labels = 0; // No longer compiles - if ( ( labels & Label_A ) == 0 ) { ... } // Also does not compile - - The solution is to use named bit constants, including the one for 0: - - LOKI_BIT_CONST( Labels_t, Label_None, 0 ); // 0x0000 - No bit is set - Labels_t labels = Label_None; // Or just Labels_t labels; - constructor initializes to 0 - if ( ( labels & Label_A ) == Label_None ) { ... } // // Or just if ( labels & Label_A ) { ... } - - 2. I/O and other operations which require integer variables and cannot be modified: - - void write_to_db( unsigned int word ); - Labels_t labels; - write_to_db( labels ); // No longer compiles - - This problem is solved by reinterpreting the bit fields as an integer, the user is responsible for using the right - type of integer: - - write_to_db( *((Labels_t::bit_word_t*)(&labels)) ); - - ========================================================================================================================================== -*/ - -/// @par Non-Templated Initialization. -/// Not all compilers support template member functions where the template -/// arguments are not deduced but explicitly specified. For these broken -/// compilers, a non-template make_bit_const() function is provided instead of -/// 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 -#endif - -/// @par Forbidding Conversions. -/// This incomplete type prevents compilers from instantiating templates for -/// type conversions which should not happen. This incomplete type must be a -/// template: if the type is incomplete at the point of template definition, -/// the template is illegal (although the standard allows compilers to accept -/// or reject such code, §14.6/, so some compilers will not issue diagnostics -/// unless template is instantiated). The standard-compliant way is to defer -/// binding to the point of instantiation by making the incomplete type itself -/// a template. -template < typename > struct Forbidden_conversion; // This struct must not be defined! - -/// Forward declaration of the field type. -template < -unsigned int unique_index, - typename word_t = unsigned long - > class SafeBitField; - -//////////////////////////////////////////////////////////////////////////////// -/// \class SafeBitConst Bit constants. -/// This class defines a bit-field constant - a collection of unchanging bits -/// used to compare to bit-fields. Instances of this class are intended to act -/// as labels for bit-fields. -/// -/// \par Safety -/// - This class provides operations used for comparisons and conversions, but -/// no operations which may modify the value. -/// - As a templated class, it provides type-safety so bit values and constants -/// used for different reasons may not be unknowingly compared to each other. -/// - The unique_index template parameter insures the unique type of each bit -/// bit-field. It shares the unique_index with a similar SafeBitField. -/// - Its operations only allow comparisons to other bit-constants and -/// bit-fields of the same type. -//////////////////////////////////////////////////////////////////////////////// - -template -< -unsigned int unique_index, - typename word_t = unsigned long - > -class SafeBitConst -{ -public: - - /// Type of the bit field is available if needed. - typedef word_t bit_word_t; - /// Corresponding field type. - typedef SafeBitField< unique_index, word_t > field_t; - /// Typedef is not allowed in friendship declaration. - friend class SafeBitField< unique_index, word_t >; - - // Static factory constructor, creates a bit constant with one bit set. The position of the bit is given by the template parameter, - // bit 1 is the junior bit, i.e. make_bit_const<1>() returns 1. Bit index 0 is a special case and returns 0. - // This function should be used only to initialize the static bit constant objects. - // This function will not compile if the bit index is outside the vaild range. - // There is also a compile-time assert to make sure the size of the class is the same as the size of the underlaying integer type. - // This assert could go into the constructor, but aCC does not seem to understand sizeof(SafeBitConst) in the constructor. - // -#ifndef LOKI_BIT_FIELD_NONTEMPLATE_INIT - template < unsigned int i > static SafeBitConst make_bit_const() - { - LOKI_STATIC_CHECK( i <= ( 8 * sizeof(word_t) ), Index_is_beyond_size_of_data ); - LOKI_STATIC_CHECK( sizeof(SafeBitConst) == sizeof(word_t), Object_size_does_not_match_data_size ); - // Why check for ( i > 0 ) again inside the shift if the shift - // can never be evaluated for i == 0? Some compilers see shift by ( i - 1 ) - // and complain that for i == 0 the number is invalid, without - // checking that shift needs evaluating. - return SafeBitConst( ( i > 0 ) ? ( word_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0 ); - } -#else - static SafeBitConst make_bit_const( unsigned int i ) - { - LOKI_STATIC_CHECK( sizeof(SafeBitConst) == sizeof(word_t), Object_size_does_not_match_data_size ); - assert( i <= ( 8 * sizeof(word_t) ) ); // Index is beyond size of data. - // Why check for ( i > 0 ) again inside the shift if the shift - // can never be evaluated for i == 0? Some compilers see shift by ( i - 1 ) - // and complain that for i == 0 the number is invalid, without - // checking that shift needs evaluating. - return SafeBitConst( ( i > 0 ) ? ( word_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0 ); - } -#endif - - /// Default constructor allows client code to construct bit fields on the stack. - SafeBitConst() : word( 0 ) {} - - /// Copy constructor. - 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; } - - /// 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; } - - /// 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 ~ ( 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 ); } - - /// The shift operators move bits inside the bit field. These are useful in - /// loops which act over bit fields and increment them. - const SafeBitConst operator << ( unsigned int s ) const { return SafeBitConst( word << s ); } - const SafeBitConst operator >> ( unsigned int s ) const { return SafeBitConst( word >> s ); } - - /// Word size is also the maximum number of different bit fields for a given word type. - static size_t size() { return ( 8 * sizeof( word_t ) ); } - -private: - - /// Copy-assignment operator is not implemented since it does not make sense - /// for a constant object. - SafeBitConst operator = ( const SafeBitConst& rhs ); - - // Private constructor from an integer type. - explicit SafeBitConst( word_t init ) : word( init ) {} - - /// This data stores a single bit value. It is declared const to enforce - // constness for all functions of this class. - const word_t word; - - // Here comes the interesting stuff: all the operators designed to - // trap unintended conversions and make them not compile. - // Operators below handle code like this: - // SafeBitField<1> label1; - // SafeBitField<2> label2; - // if ( label1 & label2 ) { ... } - - // These operators are private, and will not instantiate in any - // event because of the incomplete Forbidden_conversion struct. - template < typename T > SafeBitConst operator|( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitConst operator&( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitConst operator^( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitConst operator|=( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitConst operator&=( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitConst operator^=( T ) const { Forbidden_conversion< T > wrong; return *this; } - - // And the same thing for comparisons: private and unusable. - // if ( label1 == label2 ) { ... } - template < typename T > bool operator==( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator!=( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator<( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator>( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator<=( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator>=( const T ) const { Forbidden_conversion< T > wrong; return true; } -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \class SafeBitConst Bit constants. -/// This class defines a bit-field constant - a collection of unchanging bits -/// used to compare to bit-fields. Instances of this class are intended to -/// store bit values. -/// -/// \par Safety -/// - This class provides operations used for comparisons and conversions, and -/// also operations which may safely modify the value. -/// - As a templated class, it provides type-safety so bit values and constants -/// used for different reasons may not be unknowingly compared to each other. -/// - The unique_index template parameter insures the unique type of each bit -/// bit-field. It shares the unique_index with a similar SafeBitConst. -/// - Its operations only allow comparisons to other bit-constants and -/// bit-fields of the same type. -//////////////////////////////////////////////////////////////////////////////// - -template -< -unsigned int unique_index, - typename word_t - > -class SafeBitField -{ -public: - - /// Type of the bit field is available if needed. - typedef word_t bit_word_t; - /// Corresponding field type. - typedef SafeBitConst< unique_index, word_t > const_t; - /// Typedef is not allowed in friendship declaration. - friend class SafeBitConst<unique_index, word_t>; - - /// Default constructor allows client code to construct bit fields on the stack. - 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; } - - /// 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; } - - /// 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; } - - /// 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; } - - /// 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 ~ ( 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 ); } - - /// Bitwise operators that use bit-constants. - SafeBitField operator | ( const_t rhs ) const { return SafeBitField( word | rhs.word ); } - SafeBitField operator & ( const_t rhs ) const { return SafeBitField( word & rhs.word ); } - SafeBitField operator ^ ( const_t rhs ) const { return SafeBitField( word ^ rhs.word ); } - SafeBitField operator |= ( const_t rhs ) { word |= rhs.word; return SafeBitField( *this ); } - SafeBitField operator &= ( const_t rhs ) { word &= rhs.word; return SafeBitField( *this ); } - SafeBitField operator ^= ( const_t rhs ) { word ^= rhs.word; return SafeBitField( *this ); } - - // Conversion to bool. - // This is a major source of headaches, but it's required to support code like this: - // const static SafeBitConst<1> Label_value = SafeBitConst<1>::make_bit_const<1>(); - // SafeBitField<1> label; - // if ( label & Label_value ) { ... } // Nice... - // - // The downside is that this allows all sorts of nasty conversions. Without additional precautions, bit fields of different types - // can be converted to bool and then compared or operated on: - // SafeBitField<1> label1; - // SafeBitField<2> label2; - // if ( label1 == label2 ) { ... } // Yuck! - // if ( label1 & label2 ) { ... } // Blech! - // - // It is somewhat safer to convert to a pointer, at least pointers to different types cannot be readilly compared, and there are no - // bitwise operations on pointers, but the conversion from word_t to a pointer can have run-time cost if they are of different size. - // - operator const bool() const { return ( 0 != word ); } - - // Shift operators shift bits inside the bit field. Does not make - // sense, most of the time, except perhaps to loop over labels and - // increment them. - SafeBitField operator << ( unsigned int s ) { return SafeBitField( word << s ); } - SafeBitField operator >> ( unsigned int s ) { return SafeBitField( word >> s ); } - SafeBitField operator <<= ( unsigned int s ) { word <<= s; return *this; } - SafeBitField operator >>= ( unsigned int s ) { word >>= s; return *this; } - - // Word size is also the maximum number of different bit fields for - // a given word type. - static size_t size( void ) { return ( 8 * sizeof( word_t ) ); } - -private: - - /// Private constructor from an integer type. Don't put too much stock into - /// explicit declaration, it's better than nothing but does not solve all - /// problems with undesired conversions because SafeBitField coverts to bool. - explicit SafeBitField( word_t init ) : word( init ) {} - - /// This stores the bits. - word_t word; - - // Here comes the interesting stuff: all the operators designed to - // trap unintended conversions and make them not compile. - // Operators below handle code like this: - // SafeBitField<1> label1; - // SafeBitField<2> label2; - // if ( label1 & label2 ) { ... } - - // These operators are private, and will not instantiate in any - // event because of the incomplete Forbidden_conversion struct. - template < typename T > SafeBitField operator | ( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitField operator & ( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitField operator ^ ( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitField operator |= ( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitField operator &= ( T ) const { Forbidden_conversion< T > wrong; return *this; } - template < typename T > SafeBitField operator ^= ( T ) const { Forbidden_conversion< T > wrong; return *this; } - - // And the same thing for comparisons: - // if ( label1 == label2 ) { ... } - template < typename T > bool operator == ( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator != ( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator < ( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator > ( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator <= ( const T ) const { Forbidden_conversion< T > wrong; return true; } - template < typename T > bool operator >= ( const T ) const { Forbidden_conversion< T > wrong; return true; } -}; - -// The above template member operators catch errors when the first -// argument to a binary operator is a label, but they don't work when -// the first argument is an integer and the second one is a label: the -// label converts to bool and the operator is performed on two integers. -// These operators catch errors like this: -// SafeBitField<1> label1; -// SafeBitField<2> label2; -// if ( !label1 & label2 ) { ... } -// where the first label is converted to bool (these errors cannot be -// caught by member operators of SafeBitField class because the first -// argument is not SafeBitField but bool. -// -// If used, these operators will not instantiate because of the -// incomplete Forbidden_conversion struct. - -template < unsigned int unique_index, typename word_t > -inline SafeBitField< unique_index, word_t > operator & ( bool, SafeBitField< unique_index, word_t > rhs ) -{ - Forbidden_conversion<word_t> wrong; - return rhs; -} - -template < unsigned int unique_index, typename word_t > -inline SafeBitField< unique_index, word_t > operator | ( bool, SafeBitField< unique_index, word_t > rhs ) -{ - Forbidden_conversion< word_t > wrong; - return rhs; -} - -template < unsigned int unique_index, typename word_t > -inline SafeBitField< unique_index, word_t > operator ^ ( bool, SafeBitField< unique_index, word_t > rhs ) -{ - Forbidden_conversion< word_t > wrong; - return rhs; -} - -template < unsigned int unique_index, typename word_t > -inline SafeBitField< unique_index, word_t > operator == ( bool, SafeBitField< unique_index, word_t > rhs ) -{ - Forbidden_conversion< word_t > wrong; - return rhs; -} - -template < unsigned int unique_index, typename word_t > -inline SafeBitField< unique_index, word_t > operator != ( bool, SafeBitField< unique_index, word_t > rhs ) -{ - Forbidden_conversion< word_t > wrong; - return rhs; -} - -// Finally, few macros. All macros are conditionally defined to use the SafeBitField classes if LOKI_SAFE_BIT_FIELD is defined. Otherwise, -// the macros fall back on the use of typedefs and integer constants. This provides no addititonal safety but allows the code to support the -// mixture of compilers which are broken to different degrees. -#define LOKI_SAFE_BIT_FIELD - -// The first macro helps to declare new bit field types: -// LOKI_BIT_FIELD( ulong ) field_t; -// 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> -#else -#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 ) \ - 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 ) \ - static const field_t::const_t label = field_t::const_t::make_bit_const( bit_index ) -#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 ) -#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 -#else -#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() -#else -#define LOKI_BIT_FIELD_COUNT( field_t ) ( 8 * sizeof(field_t) ) -#endif // LOKI_SAFE_BIT_FIELD - -} // namespace Loki - -#endif // LOKI_INCLUDED_SAFE_BIT_FIELDS_H diff --git a/shared/loki/SafeFormat.h b/shared/loki/SafeFormat.h deleted file mode 100644 index bd2837f9..00000000 --- a/shared/loki/SafeFormat.h +++ /dev/null @@ -1,682 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2005 by Andrei Alexandrescu -// 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 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 -// warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SAFEFORMAT_INC_ -#define LOKI_SAFEFORMAT_INC_ - -// $Id: SafeFormat.h 911 2008-12-15 20:55:24Z syntheticpp $ - - -//////////////////////////////////////////////////////////////////////////////// -// 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 -//////////////////////////////////////////////////////////////////////////////// - -#include <cstdio> -#include <climits> -#include <string> -#include <cstring> -#include <stdexcept> -#include <utility> -#include <cassert> -#include <locale> -#include <iostream> - -#include <loki/LokiExport.h> - - -// long is 32 bit on 64-bit Windows! -// intptr_t used to get 64 bit on Win64 -#if defined(_WIN32) || defined(_WIN64) -# define LOKI_SAFEFORMAT_SIGNED_LONG intptr_t -# define LOKI_SAFEFORMAT_UNSIGNED_LONG uintptr_t -#else -# define LOKI_SAFEFORMAT_SIGNED_LONG signed long -# define LOKI_SAFEFORMAT_UNSIGNED_LONG unsigned long -#endif - -// Windows headers could have min/max defined -#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; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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() - { - } - -#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) -#if (defined(_WIN32) || defined(_WIN64)) - LOKI_PRINTF_STATE_FORWARD(unsigned long) -#else - // 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_; - 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)); - } - } - 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()(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; - } - 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); - } - else - { - Fill(' ', width_ - len); - Write(s, s + len); - } - } - else - { - Write(s, s + len); - } - 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; - } - 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; - } - } - 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(); - } - - 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; - } - - 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 -#else - _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 - } - - void Fill(const Char c, size_t n) - { - for (; n > 0; --n) - { - Write(&c, &c + 1); - } - } - - 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; - } - - 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; - } - - 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; - } - // It's a "%%" - Write(begin, ++format_); - begin = ++format_; - continue; - } - if (*format_ == 0) - { - Write(begin, format_); - break; - } - ++format_; - } - } - - 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 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 ReadLeaders() - { - ReadFlags(); - ReadWidth(); - if (*format_ == '.') ReadPrecision(); - ReadModifiers(); - } - - 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; - } - - // 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> Printf(const char* format); - -LOKI_EXPORT -PrintfState<std::FILE*, char> Printf(const std::string& format); - -LOKI_EXPORT -PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const char* format); - -LOKI_EXPORT -PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const std::string& format); - -LOKI_EXPORT -PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const char* format); - -LOKI_EXPORT -PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const std::string& format); - -LOKI_EXPORT -PrintfState<std::string&, char> SPrintf(std::string& s, const char* format); - -LOKI_EXPORT -PrintfState<std::string&, char> SPrintf(std::string& s, const std::string& 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 - - -#endif // end file guardian - diff --git a/shared/loki/ScopeGuard.h b/shared/loki/ScopeGuard.h deleted file mode 100644 index 99ce569d..00000000 --- a/shared/loki/ScopeGuard.h +++ /dev/null @@ -1,669 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2000 Andrei Alexandrescu -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SCOPEGUARD_INC_ -#define LOKI_SCOPEGUARD_INC_ - -// $Id: ScopeGuard.h 799 2006-12-20 00:37:13Z rich_sposato $ - - -#include "RefToValue.h" - -/// \defgroup ExceptionGroup Exception-safe code - -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 (...) - {} - } - - 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); - } - - ~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 -#define LOKI_CONCATENATE(s1, s2) LOKI_CONCATENATE_DIRECT(s1, s2) -#define LOKI_ANONYMOUS_VARIABLE(str) LOKI_CONCATENATE(str, __LINE__) - -#define LOKI_ON_BLOCK_EXIT ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard -#define LOKI_ON_BLOCK_EXIT_OBJ ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeObjGuard - -//by ZenJu -#define LOKI_ON_BLOCK_EXIT2(X) ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard([&](){X;}); (void)LOKI_ANONYMOUS_VARIABLE(scopeGuard); - -#endif // end file guardian - diff --git a/shared/loki/Sequence.h b/shared/loki/Sequence.h deleted file mode 100644 index 04a64174..00000000 --- a/shared/loki/Sequence.h +++ /dev/null @@ -1,49 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SEQUENCE_INC_ -#define LOKI_SEQUENCE_INC_ - -// $Id: Sequence.h 768 2006-10-25 20:40:40Z syntheticpp $ - - -#include "Typelist.h" - -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; -}; - -} // namespace Loki - -#endif // end file guardian - diff --git a/shared/loki/Singleton.h b/shared/loki/Singleton.h deleted file mode 100644 index 1e479032..00000000 --- a/shared/loki/Singleton.h +++ /dev/null @@ -1,889 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SINGLETON_INC_ -#define LOKI_SINGLETON_INC_ - -// $Id: Singleton.h 834 2007-08-02 19:36:10Z syntheticpp $ - - -#include "LokiExport.h" -#include "Threads.h" -#include <algorithm> -#include <stdexcept> -#include <cassert> -#include <cstdlib> -#include <new> -#include <vector> -#include <list> -#include <memory> - -#ifdef _MSC_VER -#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl -#else -#define LOKI_C_CALLING_CONVENTION_QUALIFIER -#endif - -/// \defgroup SingletonGroup Singleton -/// \defgroup CreationGroup Creation policies -/// \ingroup SingletonGroup -/// \defgroup LifetimeGroup Lifetime policies -/// \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 -/// 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 -/// Be aware of this when you use Loki::Factory, Loki::Functor, or Loki::Function. - - - -namespace Loki -{ -typedef void (LOKI_C_CALLING_CONVENTION_QUALIFIER* atexit_pfn_t)(); - -namespace Private -{ - -#ifndef LOKI_MAKE_DLL -void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below -#else -void LOKI_EXPORT AtExitFn(); -#endif - -class LifetimeTracker; - -#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; -#else -// Helper data -typedef LifetimeTracker** TrackerArray; -extern TrackerArray pTrackerArray; -extern unsigned int elements; -#endif - -//////////////////////////////////////////////////////////////////////////////// -// 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() {} - -// 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); -} - -#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); -} - -#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); -} - -//////////////////////////////////////////////////////////////////////////////// -/// \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; - - static T* Create() - { - return new (allocator.allocate(1)) T; - } - - 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 -{ - 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( disable : 4121 ) - // 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); - }; - -#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 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) - { -#ifndef ATEXIT_FIXED - if (!destroyedOnce_) -#endif - std::atexit(pFun); - } - - static void OnDeadReference() - { -#ifndef ATEXIT_FIXED - destroyedOnce_ = true; -#endif - } - -private: -#ifndef ATEXIT_FIXED - static bool destroyedOnce_; -#endif -}; - -#ifndef ATEXIT_FIXED -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: - - 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() - { - 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; -#else - 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; - -//////////////////////////////////////////////////////////////////////////////// -// class template Adapter -// Helper for SingletonWithLongevity below -//////////////////////////////////////////////////////////////////////////////// - -namespace Private -{ -template <class T> -struct Adapter -{ - void operator()(T*) { return pFun_(); } - atexit_pfn_t pFun_; -}; -} - -//////////////////////////////////////////////////////////////////////////////// -/// \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) - { - Private::Adapter<T> adapter = { pFun }; - SetLongevity(pObj, GetLongevity(pObj), adapter); - } - - 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 Init() - { - static bool done = false; - if (!done) - { - followers_ = new Container; - done = true; - } - } - - static void AddFollower(atexit_pfn_t ae) - { - Init(); - followers_->push_back(ae); - } - - static void DestroyFollowers() - { - Init(); - for (iterator it = followers_->begin(); it != followers_->end(); ++it) - (*it)(); - delete followers_; - } - }; - -public: - - /// \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: - - /// 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_) - { - MakeInstance(); - } - return *pInstance_; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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() -{ - typename ThreadingModel<SingletonHolder, MutexPolicy>::Lock guard; - (void)guard; - - if (!pInstance_) - { - if (destroyed_) - { - 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; -} - - -//////////////////////////////////////////////////////////////////////////////// -/// \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(); -}; - -} // namespace Loki - - -/// \def LOKI_SINGLETON_INSTANCE_DEFINITION(SHOLDER) -/// Convenience macro for the definition of the static Instance member function -/// Put this macro called with a SingletonHolder typedef into your cpp file. - -#define LOKI_SINGLETON_INSTANCE_DEFINITION(SHOLDER) \ - namespace Loki \ - { \ - template<> \ - SHOLDER::ObjectType& Singleton<SHOLDER::ObjectType>::Instance() \ - { \ - return SHOLDER::Instance(); \ - } \ - } - - -#endif // end file guardian - diff --git a/shared/loki/SmallObj.cpp b/shared/loki/SmallObj.cpp deleted file mode 100644 index 1c42374f..00000000 --- a/shared/loki/SmallObj.cpp +++ /dev/null @@ -1,1226 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// $Id: SmallObj.cpp 823 2007-05-08 10:48:40Z lfittl $ - - -#include "SmallObj.h" - -#include <cassert> -#include <climits> -#include <vector> -#include <bitset> - -//#define DO_EXTRA_LOKI_TESTS -//#define USE_NEW_TO_ALLOCATE -//#define LOKI_CHECK_FOR_CORRUPTION - -#ifdef DO_EXTRA_LOKI_TESTS -#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. - */ -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. - */ - 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 ); - - /** 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 ); - } - - 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: - - /** 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 ); - - /** 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 ); - - /// 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 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; - - /** 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 ) ); - } - -}; - -unsigned char FixedAllocator::MinObjectsPerChunk_ = 8; -unsigned char FixedAllocator::MaxObjectsPerChunk_ = UCHAR_MAX; - -// Chunk::Init ---------------------------------------------------------------- - -bool Chunk::Init( std::size_t blockSize, unsigned char blocks ) -{ - assert(blockSize > 0); - assert(blocks > 0); - // Overflow check - const std::size_t allocSize = blockSize * blocks; - assert( allocSize / blockSize == 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 ) ); -#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 ) ); - if ( NULL == pData_ ) return false; -#endif - - Reset( blockSize, blocks ); - return true; -} - -// Chunk::Reset --------------------------------------------------------------- - -void Chunk::Reset(std::size_t blockSize, unsigned char blocks) -{ - assert(blockSize > 0); - assert(blocks > 0); - // Overflow check - assert((blockSize * blocks) / blockSize == blocks); - - firstAvailableBlock_ = 0; - blocksAvailable_ = blocks; - - unsigned char i = 0; - for ( unsigned char* p = pData_; i != blocks; p += blockSize ) - { - *p = ++i; - } -} - -// Chunk::Release ------------------------------------------------------------- - -void Chunk::Release() -{ - assert( NULL != pData_ ); -#ifdef USE_NEW_TO_ALLOCATE - ::operator delete ( pData_ ); -#else - ::std::free( static_cast< void* >( pData_ ) ); -#endif -} - -// Chunk::Allocate ------------------------------------------------------------ - -void* Chunk::Allocate(std::size_t blockSize) -{ - if ( IsFilled() ) return NULL; - - assert((firstAvailableBlock_ * blockSize) / blockSize == - firstAvailableBlock_); - unsigned char* pResult = pData_ + (firstAvailableBlock_ * blockSize); - firstAvailableBlock_ = *pResult; - --blocksAvailable_; - - return pResult; -} - -// Chunk::Deallocate ---------------------------------------------------------- - -void Chunk::Deallocate(void* p, std::size_t blockSize) -{ - assert(p >= pData_); - - unsigned char* toRelease = static_cast<unsigned char*>(p); - // Alignment check - assert((toRelease - pData_) % blockSize == 0); - unsigned char index = static_cast< unsigned char >( - ( toRelease - pData_ ) / blockSize); - -#if defined(DEBUG) || defined(_DEBUG) - // Check if block was already deleted. Attempting to delete the same - // block more than once causes Chunk's linked-list of stealth indexes to - // become corrupt. And causes count of blocksAvailable_ to be wrong. - if ( 0 < blocksAvailable_ ) - assert( firstAvailableBlock_ != index ); -#endif - - *toRelease = firstAvailableBlock_; - firstAvailableBlock_ = index; - // Truncation check - assert(firstAvailableBlock_ == (toRelease - pData_) / blockSize); - - ++blocksAvailable_; -} - -// Chunk::IsCorrupt ----------------------------------------------------------- - -bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize, - bool checkIndexes ) const -{ - - if ( numBlocks < blocksAvailable_ ) - { - // Contents at this Chunk corrupted. This might mean something has - // overwritten memory owned by the Chunks container. - assert( false ); - return true; - } - if ( IsFilled() ) - // Useless to do further corruption checks if all blocks allocated. - return false; - unsigned char index = firstAvailableBlock_; - if ( numBlocks <= index ) - { - // Contents at this Chunk corrupted. This might mean something has - // overwritten memory owned by the Chunks container. - assert( false ); - return true; - } - if ( !checkIndexes ) - // Caller chose to skip more complex corruption tests. - return false; - - /* If the bit at index was set in foundBlocks, then the stealth index was - found on the linked-list. - */ - std::bitset< UCHAR_MAX > foundBlocks; - 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 - index was not already found while traversing the linked-list. The linked- - list should have exactly blocksAvailable_ nodes, so the for loop will not - check more than blocksAvailable_. This loop can't check inside allocated - blocks for corruption since such blocks are not within the linked-list. - Contents of allocated blocks are not changed by Chunk. - - Here are the types of corrupted link-lists which can be verified. The - corrupt index is shown with asterisks in each example. - - Type 1: Index is too big. - numBlocks == 64 - blocksAvailable_ == 7 - firstAvailableBlock_ -> 17 -> 29 -> *101* - There should be no indexes which are equal to or larger than the total - number of blocks. Such an index would refer to a block beyond the - Chunk's allocated domain. - - Type 2: Index is repeated. - numBlocks == 64 - blocksAvailable_ == 5 - firstAvailableBlock_ -> 17 -> 29 -> 53 -> *17* -> 29 -> 53 ... - No index should be repeated within the linked-list since that would - indicate the presence of a loop in the linked-list. - */ - for ( unsigned char cc = 0; ; ) - { - nextBlock = pData_ + ( index * blockSize ); - foundBlocks.set( index, true ); - ++cc; - if ( cc >= blocksAvailable_ ) - // Successfully counted off number of nodes in linked-list. - break; - index = *nextBlock; - if ( numBlocks <= index ) - { - /* This catches Type 1 corruptions as shown in above comments. - This implies that a block was corrupted due to a stray pointer - or an operation on a nearby block overran the size of the block. - */ - assert( false ); - return true; - } - if ( foundBlocks.test( index ) ) - { - /* This catches Type 2 corruptions as shown in above comments. - This implies that a block was corrupted due to a stray pointer - or an operation on a nearby block overran the size of the block. - Or perhaps the program tried to delete a block more than once. - */ - assert( false ); - return true; - } - } - if ( foundBlocks.count() != blocksAvailable_ ) - { - /* This implies that the singly-linked-list of stealth indexes was - corrupted. Ideally, this should have been detected within the loop. - */ - assert( false ); - return true; - } - - return false; -} - -// Chunk::IsBlockAvailable ---------------------------------------------------- - -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 ); - // Alignment check - assert( ( place - pData_ ) % blockSize == 0 ); - unsigned char blockIndex = static_cast< unsigned char >( - ( place - pData_ ) / blockSize ); - - unsigned char index = firstAvailableBlock_; - assert( numBlocks > index ); - if ( index == blockIndex ) - return true; - - /* If the bit at index was set in foundBlocks, then the stealth index was - found on the linked-list. - */ - std::bitset< UCHAR_MAX > foundBlocks; - unsigned char* nextBlock = NULL; - for ( unsigned char cc = 0; ; ) - { - nextBlock = pData_ + ( index * blockSize ); - foundBlocks.set( index, true ); - ++cc; - if ( cc >= blocksAvailable_ ) - // Successfully counted off number of nodes in linked-list. - break; - index = *nextBlock; - if ( index == blockIndex ) - return true; - assert( numBlocks > index ); - assert( !foundBlocks.test( index ) ); - } - - return false; -} - -// FixedAllocator::FixedAllocator --------------------------------------------- - -FixedAllocator::FixedAllocator() - : blockSize_( 0 ) - , numBlocks_( 0 ) - , chunks_( 0 ) - , allocChunk_( NULL ) - , deallocChunk_( NULL ) - , emptyChunk_( NULL ) -{ -} - -// FixedAllocator::~FixedAllocator -------------------------------------------- - -FixedAllocator::~FixedAllocator() -{ -#ifdef DO_EXTRA_LOKI_TESTS - TrimEmptyChunk(); - assert( chunks_.empty() && "Memory leak detected!" ); -#endif - for ( ChunkIter i( chunks_.begin() ); i != chunks_.end(); ++i ) - i->Release(); -} - -// FixedAllocator::Initialize ------------------------------------------------- - -void FixedAllocator::Initialize( std::size_t blockSize, std::size_t pageSize ) -{ - assert( blockSize > 0 ); - assert( pageSize >= blockSize ); - blockSize_ = blockSize; - - std::size_t numBlocks = pageSize / blockSize; - if ( numBlocks > MaxObjectsPerChunk_ ) numBlocks = MaxObjectsPerChunk_; - else if ( numBlocks < MinObjectsPerChunk_ ) numBlocks = MinObjectsPerChunk_; - - numBlocks_ = static_cast<unsigned char>(numBlocks); - assert(numBlocks_ == numBlocks); -} - -// FixedAllocator::CountEmptyChunks ------------------------------------------- - -std::size_t FixedAllocator::CountEmptyChunks( void ) const -{ -#ifdef DO_EXTRA_LOKI_TESTS - // This code is only used for specialized tests of the allocator. - // It is #ifdef-ed so that its O(C) complexity does not overwhelm the - // functions which call it. - std::size_t count = 0; - for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it ) - { - const Chunk& chunk = *it; - if ( chunk.HasAvailable( numBlocks_ ) ) - ++count; - } - return count; -#else - return ( NULL == emptyChunk_ ) ? 0 : 1; -#endif -} - -// FixedAllocator::IsCorrupt -------------------------------------------------- - -bool FixedAllocator::IsCorrupt( void ) const -{ - const bool isEmpty = chunks_.empty(); - ChunkCIter start( chunks_.begin() ); - ChunkCIter last( chunks_.end() ); - const size_t emptyChunkCount = CountEmptyChunks(); - - if ( isEmpty ) - { - if ( start != last ) - { - assert( false ); - return true; - } - if ( 0 < emptyChunkCount ) - { - assert( false ); - return true; - } - if ( NULL != deallocChunk_ ) - { - assert( false ); - return true; - } - if ( NULL != allocChunk_ ) - { - assert( false ); - return true; - } - if ( NULL != emptyChunk_ ) - { - assert( false ); - return true; - } - } - - else - { - const Chunk* front = &chunks_.front(); - const Chunk* back = &chunks_.back(); - if ( start >= last ) - { - assert( false ); - return true; - } - if ( back < deallocChunk_ ) - { - assert( false ); - return true; - } - if ( back < allocChunk_ ) - { - assert( false ); - return true; - } - if ( front > deallocChunk_ ) - { - assert( false ); - return true; - } - if ( front > allocChunk_ ) - { - assert( false ); - return true; - } - - switch ( emptyChunkCount ) - { - case 0: - if ( emptyChunk_ != NULL ) - { - assert( false ); - return true; - } - break; - case 1: - if ( emptyChunk_ == NULL ) - { - assert( false ); - return true; - } - if ( back < emptyChunk_ ) - { - assert( false ); - return true; - } - if ( front > emptyChunk_ ) - { - assert( false ); - return true; - } - if ( !emptyChunk_->HasAvailable( numBlocks_ ) ) - { - // This may imply somebody tried to delete a block twice. - assert( false ); - return true; - } - break; - default: - assert( false ); - return true; - } - for ( ChunkCIter it( start ); it != last; ++it ) - { - const Chunk& chunk = *it; - if ( chunk.IsCorrupt( numBlocks_, blockSize_, true ) ) - return true; - } - } - - return false; -} - -// FixedAllocator::HasBlock --------------------------------------------------- - -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; - if ( chunk.HasBlock( p, chunkLength ) ) - return &chunk; - } - return NULL; -} - -// FixedAllocator::TrimEmptyChunk --------------------------------------------- - -bool FixedAllocator::TrimEmptyChunk( void ) -{ - // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. - assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); - if ( NULL == emptyChunk_ ) return false; - - // If emptyChunk_ points to valid Chunk, then chunk list is not empty. - assert( !chunks_.empty() ); - // And there should be exactly 1 empty Chunk. - assert( 1 == CountEmptyChunks() ); - - Chunk* lastChunk = &chunks_.back(); - if ( lastChunk != emptyChunk_ ) - std::swap( *emptyChunk_, *lastChunk ); - assert( lastChunk->HasAvailable( numBlocks_ ) ); - lastChunk->Release(); - chunks_.pop_back(); - - if ( chunks_.empty() ) - { - allocChunk_ = NULL; - deallocChunk_ = NULL; - } - else - { - if ( deallocChunk_ == emptyChunk_ ) - { - deallocChunk_ = &chunks_.front(); - assert( deallocChunk_->blocksAvailable_ < numBlocks_ ); - } - if ( allocChunk_ == emptyChunk_ ) - { - allocChunk_ = &chunks_.back(); - assert( allocChunk_->blocksAvailable_ < numBlocks_ ); - } - } - - emptyChunk_ = NULL; - assert( 0 == CountEmptyChunks() ); - - return true; -} - -// FixedAllocator::TrimChunkList ---------------------------------------------- - -bool FixedAllocator::TrimChunkList( void ) -{ - if ( chunks_.empty() ) - { - assert( NULL == allocChunk_ ); - assert( NULL == deallocChunk_ ); - } - - if ( chunks_.size() == chunks_.capacity() ) - return false; - // Use the "make-a-temp-and-swap" trick to remove excess capacity. - Chunks( chunks_ ).swap( chunks_ ); - - return true; -} - -// FixedAllocator::MakeNewChunk ----------------------------------------------- - -bool FixedAllocator::MakeNewChunk( void ) -{ - bool allocated = false; - try - { - std::size_t size = chunks_.size(); - // Calling chunks_.reserve *before* creating and initializing the new - // Chunk means that nothing is leaked by this function in case an - // exception is thrown from reserve. - if ( chunks_.capacity() == size ) - { - if ( 0 == size ) size = 4; - chunks_.reserve( size * 2 ); - } - Chunk newChunk; - allocated = newChunk.Init( blockSize_, numBlocks_ ); - if ( allocated ) - chunks_.push_back( newChunk ); - } - catch ( ... ) - { - allocated = false; - } - if ( !allocated ) return false; - - allocChunk_ = &chunks_.back(); - deallocChunk_ = &chunks_.front(); - return true; -} - -// FixedAllocator::Allocate --------------------------------------------------- - -void* FixedAllocator::Allocate( void ) -{ - // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. - assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); - assert( CountEmptyChunks() < 2 ); - - if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() ) - { - if ( NULL != emptyChunk_ ) - { - allocChunk_ = emptyChunk_; - emptyChunk_ = NULL; - } - else - { - for ( ChunkIter i( chunks_.begin() ); ; ++i ) - { - if ( chunks_.end() == i ) - { - if ( !MakeNewChunk() ) - return NULL; - break; - } - if ( !i->IsFilled() ) - { - allocChunk_ = &*i; - break; - } - } - } - } - else if ( allocChunk_ == emptyChunk_) - // detach emptyChunk_ from allocChunk_, because after - // calling allocChunk_->Allocate(blockSize_); the chunk - // is no longer empty. - emptyChunk_ = NULL; - - assert( allocChunk_ != NULL ); - assert( !allocChunk_->IsFilled() ); - void* place = allocChunk_->Allocate( blockSize_ ); - - // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. - assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); - assert( CountEmptyChunks() < 2 ); -#ifdef LOKI_CHECK_FOR_CORRUPTION - if ( allocChunk_->IsCorrupt( numBlocks_, blockSize_, true ) ) - { - assert( false ); - return NULL; - } -#endif - - return place; -} - -// FixedAllocator::Deallocate ------------------------------------------------- - -bool FixedAllocator::Deallocate( void* p, Chunk* hint ) -{ - assert(!chunks_.empty()); - assert(&chunks_.front() <= deallocChunk_); - assert(&chunks_.back() >= deallocChunk_); - assert( &chunks_.front() <= allocChunk_ ); - assert( &chunks_.back() >= allocChunk_ ); - assert( CountEmptyChunks() < 2 ); - - Chunk* foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint; - if ( NULL == foundChunk ) - return false; - - assert( foundChunk->HasBlock( p, numBlocks_ * blockSize_ ) ); -#ifdef LOKI_CHECK_FOR_CORRUPTION - if ( foundChunk->IsCorrupt( numBlocks_, blockSize_, true ) ) - { - assert( false ); - return false; - } - if ( foundChunk->IsBlockAvailable( p, numBlocks_, blockSize_ ) ) - { - assert( false ); - return false; - } -#endif - deallocChunk_ = foundChunk; - DoDeallocate(p); - assert( CountEmptyChunks() < 2 ); - - return true; -} - -// FixedAllocator::VicinityFind ----------------------------------------------- - -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; - - // Special case: deallocChunk_ is the last in the array - if (hi == hiBound) hi = NULL; - - for (;;) - { - if (lo) - { - if ( lo->HasBlock( p, chunkLength ) ) return lo; - if ( lo == loBound ) - { - lo = NULL; - if ( NULL == hi ) break; - } - else --lo; - } - - if (hi) - { - if ( hi->HasBlock( p, chunkLength ) ) return hi; - if ( ++hi == hiBound ) - { - hi = NULL; - if ( NULL == lo ) break; - } - } - } - - return NULL; -} - -// FixedAllocator::DoDeallocate ----------------------------------------------- - -void FixedAllocator::DoDeallocate(void* p) -{ - // Show that deallocChunk_ really owns the block at address p. - assert( deallocChunk_->HasBlock( p, numBlocks_ * blockSize_ ) ); - // Either of the next two assertions may fail if somebody tries to - // delete the same block twice. - assert( emptyChunk_ != deallocChunk_ ); - assert( !deallocChunk_->HasAvailable( numBlocks_ ) ); - // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. - assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); - - // call into the chunk, will adjust the inner list but won't release memory - deallocChunk_->Deallocate(p, blockSize_); - - if ( deallocChunk_->HasAvailable( numBlocks_ ) ) - { - assert( emptyChunk_ != deallocChunk_ ); - // deallocChunk_ is empty, but a Chunk is only released if there are 2 - // empty chunks. Since emptyChunk_ may only point to a previously - // cleared Chunk, if it points to something else besides deallocChunk_, - // then FixedAllocator currently has 2 empty Chunks. - if ( NULL != emptyChunk_ ) - { - // 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(); - if ( lastChunk == deallocChunk_ ) - deallocChunk_ = emptyChunk_; - else if ( lastChunk != emptyChunk_ ) - std::swap( *emptyChunk_, *lastChunk ); - assert( lastChunk->HasAvailable( numBlocks_ ) ); - lastChunk->Release(); - chunks_.pop_back(); - if ( ( allocChunk_ == lastChunk ) || allocChunk_->IsFilled() ) - allocChunk_ = deallocChunk_; - } - emptyChunk_ = deallocChunk_; - } - - // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. - assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); -} - -// GetOffset ------------------------------------------------------------------ -/// @ingroup SmallObjectGroupInternal -/// Calculates index into array where a FixedAllocator of numBytes is located. -inline std::size_t GetOffset( std::size_t numBytes, std::size_t alignment ) -{ - const std::size_t alignExtra = alignment - 1; - return ( numBytes + alignExtra ) / alignment; -} - -// DefaultAllocator ----------------------------------------------------------- -/** @ingroup SmallObjectGroupInternal - Calls the default allocator when SmallObjAllocator decides not to handle a - request. SmallObjAllocator calls this if the number of bytes is bigger than - the size which can be handled by any FixedAllocator. - @param numBytes number of bytes - @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 ) -{ -#ifdef USE_NEW_TO_ALLOCATE - return doThrow ? ::operator new( numBytes ) : - ::operator new( numBytes, std::nothrow_t() ); -#else - void* p = ::std::malloc( numBytes ); - if ( doThrow && ( NULL == p ) ) - throw std::bad_alloc(); - return p; -#endif -} - -// DefaultDeallocator --------------------------------------------------------- -/** @ingroup SmallObjectGroupInternal - Calls default deallocator when SmallObjAllocator decides not to handle a - request. The default deallocator could be the global delete operator or the - free function. The free function is the preferred default deallocator since - 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 ) -{ -#ifdef USE_NEW_TO_ALLOCATE - ::operator delete( p ); -#else - ::std::free( p ); -#endif -} - -// SmallObjAllocator::SmallObjAllocator --------------------------------------- - -SmallObjAllocator::SmallObjAllocator( std::size_t pageSize, - std::size_t maxObjectSize, std::size_t objectAlignSize ) : - pool_( NULL ), - maxSmallObjectSize_( maxObjectSize ), - objectAlignSize_( objectAlignSize ) -{ -#ifdef DO_EXTRA_LOKI_TESTS - std::cout << "SmallObjAllocator " << this << std::endl; -#endif - assert( 0 != objectAlignSize ); - const std::size_t allocCount = GetOffset( maxObjectSize, objectAlignSize ); - pool_ = new FixedAllocator[ allocCount ]; - for ( std::size_t i = 0; i < allocCount; ++i ) - pool_[ i ].Initialize( ( i + 1 ) * objectAlignSize, pageSize ); -} - -// SmallObjAllocator::~SmallObjAllocator -------------------------------------- - -SmallObjAllocator::~SmallObjAllocator( void ) -{ -#ifdef DO_EXTRA_LOKI_TESTS - std::cout << "~SmallObjAllocator " << this << std::endl; -#endif - delete [] pool_; -} - -// SmallObjAllocator::TrimExcessMemory ---------------------------------------- - -bool SmallObjAllocator::TrimExcessMemory( void ) -{ - bool found = false; - const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - std::size_t i = 0; - for ( ; i < allocCount; ++i ) - { - if ( pool_[ i ].TrimEmptyChunk() ) - found = true; - } - for ( i = 0; i < allocCount; ++i ) - { - if ( pool_[ i ].TrimChunkList() ) - found = true; - } - - return found; -} - -// SmallObjAllocator::Allocate ------------------------------------------------ - -void* SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) -{ - if ( numBytes > GetMaxObjectSize() ) - return DefaultAllocator( numBytes, doThrow ); - - assert( NULL != pool_ ); - if ( 0 == numBytes ) numBytes = 1; - const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1; - const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - (void) allocCount; - assert( index < allocCount ); - - FixedAllocator& allocator = pool_[ index ]; - assert( allocator.BlockSize() >= numBytes ); - assert( allocator.BlockSize() < numBytes + GetAlignment() ); - void* place = allocator.Allocate(); - - if ( ( NULL == place ) && TrimExcessMemory() ) - place = allocator.Allocate(); - - if ( ( NULL == place ) && doThrow ) - { -#ifdef _MSC_VER - throw std::bad_alloc( "could not allocate small object" ); -#else - // GCC did not like a literal string passed to std::bad_alloc. - // so just throw the default-constructed exception. - throw std::bad_alloc(); -#endif - } - return place; -} - -// SmallObjAllocator::Deallocate ---------------------------------------------- - -void SmallObjAllocator::Deallocate( void* p, std::size_t numBytes ) -{ - if ( NULL == p ) return; - if ( numBytes > GetMaxObjectSize() ) - { - DefaultDeallocator( p ); - return; - } - assert( NULL != pool_ ); - if ( 0 == numBytes ) numBytes = 1; - const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1; - const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - (void) allocCount; - assert( index < allocCount ); - FixedAllocator& allocator = pool_[ index ]; - assert( allocator.BlockSize() >= numBytes ); - assert( allocator.BlockSize() < numBytes + GetAlignment() ); - const bool found = allocator.Deallocate( p, NULL ); - (void) found; - assert( found ); -} - -// SmallObjAllocator::Deallocate ---------------------------------------------- - -void SmallObjAllocator::Deallocate( void* p ) -{ - if ( NULL == p ) return; - assert( NULL != pool_ ); - FixedAllocator* pAllocator = NULL; - const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - Chunk* chunk = NULL; - - for ( std::size_t ii = 0; ii < allocCount; ++ii ) - { - chunk = pool_[ ii ].HasBlock( p ); - if ( NULL != chunk ) - { - pAllocator = &pool_[ ii ]; - break; - } - } - if ( NULL == pAllocator ) - { - DefaultDeallocator( p ); - return; - } - - assert( NULL != chunk ); - const bool found = pAllocator->Deallocate( p, chunk ); - (void) found; - assert( found ); -} - -// SmallObjAllocator::IsCorrupt ----------------------------------------------- - -bool SmallObjAllocator::IsCorrupt( void ) const -{ - if ( NULL == pool_ ) - { - assert( false ); - return true; - } - if ( 0 == GetAlignment() ) - { - assert( false ); - return true; - } - if ( 0 == GetMaxObjectSize() ) - { - assert( false ); - return true; - } - const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - for ( std::size_t ii = 0; ii < allocCount; ++ii ) - { - if ( pool_[ ii ].IsCorrupt() ) - return true; - } - return false; -} - -} // end namespace Loki - diff --git a/shared/loki/SmallObj.h b/shared/loki/SmallObj.h deleted file mode 100644 index 10624cc2..00000000 --- a/shared/loki/SmallObj.h +++ /dev/null @@ -1,644 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SMALLOBJ_INC_ -#define LOKI_SMALLOBJ_INC_ - -// $Id: SmallObj.h 806 2007-02-03 00:01:52Z rich_sposato $ - - -#include "LokiExport.h" -#include "Threads.h" -#include "Singleton.h" -#include <cstddef> -#include <new> // needed for std::nothrow_t parameter. - -#ifndef LOKI_DEFAULT_CHUNK_SIZE -#define LOKI_DEFAULT_CHUNK_SIZE 4096 -#endif - -#ifndef LOKI_MAX_SMALL_OBJECT_SIZE -#define LOKI_MAX_SMALL_OBJECT_SIZE 256 -#endif - -#ifndef LOKI_DEFAULT_OBJECT_ALIGNMENT -#define LOKI_DEFAULT_OBJECT_ALIGNMENT 4 -#endif - -#ifndef LOKI_DEFAULT_SMALLOBJ_LIFETIME -#define LOKI_DEFAULT_SMALLOBJ_LIFETIME ::Loki::LongevityLifetime::DieAsSmallObjectParent -#endif - -#if defined(LOKI_SMALL_OBJECT_USE_NEW_ARRAY) && defined(_MSC_VER) -#pragma message("Don't define LOKI_SMALL_OBJECT_USE_NEW_ARRAY when using a Microsoft compiler to prevent memory leaks.") -#pragma message("now calling '#undef LOKI_SMALL_OBJECT_USE_NEW_ARRAY'") -#undef LOKI_SMALL_OBJECT_USE_NEW_ARRAY -#endif - -/// \defgroup SmallObjectGroup Small objects -/// -/// \defgroup SmallObjectGroupInternal Internals -/// \ingroup SmallObjectGroup - -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. - */ -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: - - /// 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 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 ) -{ - 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 - 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 ); - } - -#ifdef LOKI_SMALL_OBJECT_USE_NEW_ARRAY - - /// 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. - -#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 - -#endif // end file guardian - diff --git a/shared/loki/SmartPtr.h b/shared/loki/SmartPtr.h deleted file mode 100644 index 6f6f9996..00000000 --- a/shared/loki/SmartPtr.h +++ /dev/null @@ -1,1778 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_SMARTPTR_INC_ -#define LOKI_SMARTPTR_INC_ - -// $Id: SmartPtr.h 903 2008-11-10 05:55:12Z rich_sposato $ - - -/// \defgroup SmartPointerGroup Smart pointers -/// Policy based implementation of a smart pointer -/// \defgroup SmartPointerOwnershipGroup Ownership policies -/// \ingroup SmartPointerGroup -/// \defgroup SmartPointerStorageGroup Storage policies -/// \ingroup SmartPointerGroup -/// \defgroup SmartPointerConversionGroup Conversion policies -/// \ingroup SmartPointerGroup -/// \defgroup SmartPointerCheckingGroup Checking policies -/// \ingroup SmartPointerGroup - -#include "LokiExport.h" -#include "SmallObj.h" -#include "TypeManip.h" -#include "static_check.h" -#include "RefToValue.h" -#include "ConstPolicy.h" - -#include <functional> -#include <stdexcept> -#include <cassert> -#include <string> - -#if !defined(_MSC_VER) -# if defined(__sparc__) -# include <inttypes.h> -# else -# include <stdint.h> -# endif -#endif - -#if defined(_MSC_VER) || defined(__GNUC__) -// GCC>=4.1 must use -ffriend-injection due to a bug in GCC -#define LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND -#endif - - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class HeapStorage -/// -/// \ingroup SmartPointerStorageGroup -/// Implementation of the StoragePolicy used by SmartPtr. Uses explicit call -/// to T's destructor followed by call to free. -//////////////////////////////////////////////////////////////////////////////// - - -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()) - {} - - // 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) - {} - - HeapStorage(const StoredType& p) : pointee_(p) {} - - PointerType operator->() const { return pointee_; } - - ReferenceType operator*() const { return *pointee_; } - - void Swap(HeapStorage& rhs) - { std::swap(pointee_, rhs.pointee_); } - - // 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 typename HeapStorage<F>::StoredType& GetImplRef(HeapStorage<F>& sp); - -protected: - // Destroys the data stored - // (Destruction might be taken over by the OwnershipPolicy) - void Destroy() - { - if ( 0 != pointee_ ) - { - pointee_->~T(); - ::free( pointee_ ); - } - } - - // Default value to initialize the pointer - static StoredType Default() - { return 0; } - -private: - // Data - StoredType 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 typename HeapStorage<T>::StoredType& GetImplRef(HeapStorage<T>& sp) -{ return sp.pointee_; } - - -//////////////////////////////////////////////////////////////////////////////// -/// \class DefaultSPStorage -/// -/// \ingroup SmartPointerStorageGroup -/// Implementation of the StoragePolicy used by SmartPtr -//////////////////////////////////////////////////////////////////////////////// - - -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()) - {} - - // 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) - {} - - DefaultSPStorage(const StoredType& p) : pointee_(p) {} - - PointerType operator->() const { return pointee_; } - - ReferenceType operator*() const { return *pointee_; } - - void Swap(DefaultSPStorage& rhs) - { std::swap(pointee_, rhs.pointee_); } - - // 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 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_; - } - - // Default value to initialize the pointer - static StoredType Default() - { return 0; } - -private: - // Data - StoredType 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 typename DefaultSPStorage<T>::StoredType& GetImplRef(DefaultSPStorage<T>& sp) -{ return sp.pointee_; } - - -//////////////////////////////////////////////////////////////////////////////// -/// \class LockedStorage -/// -/// \ingroup SmartPointerStorageGroup -/// Implementation of the StoragePolicy used by SmartPtr. -/// -/// Each call to operator-> locks the object for the duration of a call to a -/// member function of T. -/// -/// \par How It Works -/// LockedStorage has a helper class called Locker, which acts as a smart -/// pointer with limited abilities. LockedStorage::operator-> returns an -/// unnamed temporary of type Locker<T> that exists for the duration of the -/// call to a member function of T. The unnamed temporary locks the object -/// when it is constructed by operator-> and unlocks the object when it is -/// destructed. -/// -/// \note This storage policy requires class T to have member functions Lock -/// and Unlock. If your class does not have Lock or Unlock functions, you may -/// either make a child class which does, or make a policy class similar to -/// LockedStorage which calls other functions to lock the object. -//////////////////////////////////////////////////////////////////////////////// - -template <class T> -class Locker -{ -public: - Locker( const T* p ) : pointee_( const_cast< T* >( p ) ) - { - if ( pointee_ != 0 ) - pointee_->Lock(); - } - - ~Locker( void ) - { - if ( pointee_ != 0 ) - pointee_->Unlock(); - } - - operator T* () - { - return pointee_; - } - - T* operator->() - { - return pointee_; - } - -private: - Locker( void ); - Locker& operator = ( const Locker& ); - T* pointee_; -}; - -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* - - LockedStorage() : pointee_( Default() ) {} - - ~LockedStorage( void ) {} - - LockedStorage( const LockedStorage&) : pointee_( 0 ) {} - - LockedStorage( const StoredType& p ) : pointee_( p ) {} - - PointerType operator->() - { - return Locker< T >( pointee_ ); - } - - void Swap(LockedStorage& rhs) - { - std::swap( pointee_, rhs.pointee_ ); - } - - // 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 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_; - } - - // Default value to initialize the pointer - static StoredType Default() - { return 0; } - -private: - /// Dereference operator is not implemented. - ReferenceType operator*(); - - // Data - StoredType 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 typename LockedStorage<T>::StoredType& GetImplRef(LockedStorage<T>& sp) -{ return sp.pointee_; } - - -//////////////////////////////////////////////////////////////////////////////// -/// \class ArrayStorage -/// -/// \ingroup SmartPointerStorageGroup -/// Implementation of the ArrayStorage used by SmartPtr -//////////////////////////////////////////////////////////////////////////////// - - -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()) - {} - - // 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) - {} - - ArrayStorage(const StoredType& p) : pointee_(p) {} - - PointerType operator->() const { return pointee_; } - - ReferenceType operator*() const { return *pointee_; } - - void Swap(ArrayStorage& rhs) - { std::swap(pointee_, rhs.pointee_); } - - // 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 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_; } - - // Default value to initialize the pointer - static StoredType Default() - { return 0; } - -private: - // Data - StoredType 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 typename ArrayStorage<T>::StoredType& GetImplRef(ArrayStorage<T>& sp) -{ return sp.pointee_; } - - -//////////////////////////////////////////////////////////////////////////////// -/// \class RefCounted -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Provides a classic external reference counting implementation -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -class RefCounted -{ -public: - RefCounted() - : pCount_(static_cast<uintptr_t*>( - SmallObject<>::operator new(sizeof(uintptr_t)))) - { - assert(pCount_ != 0); - *pCount_ = 1; - } - - RefCounted(const RefCounted& rhs) - : pCount_(rhs.pCount_) - {} - - // 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; - } - - bool Release(const P&) - { - if (!--*pCount_) - { - SmallObject<>::operator delete(pCount_, sizeof(uintptr_t)); - pCount_ = NULL; - return true; - } - return false; - } - - void Swap(RefCounted& rhs) - { std::swap(pCount_, rhs.pCount_); } - - enum { destructiveCopy = false }; - -private: - // Data - uintptr_t* pCount_; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct RefCountedMT -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Implements external reference counting for multithreaded programs -/// Policy Usage: RefCountedMTAdj<ThreadingModel>::RefCountedMT -/// -/// \par Warning -/// There could be a race condition, see bug "Race condition in RefCountedMTAdj::Release" -/// http://sourceforge.net/tracker/index.php?func=detail&aid=1408845&group_id=29557&atid=396644 -/// As stated in bug 1408845, the Release function is not thread safe if a -/// SmartPtr copy-constructor tries to copy the last pointer to an object in -/// one thread, while the destructor is acting on the last pointer in another -/// thread. The existence of a race between a copy-constructor and destructor -/// implies a design flaw at a higher level. That race condition must be -/// 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 <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; - - 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) - : pCount_(rhs.pCount_) - {} - - //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; - } - - bool Release(const P&) - { - 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; - } - - void Swap(RefCountedMT& rhs) - { std::swap(pCount_, rhs.pCount_); } - - enum { destructiveCopy = false }; - - private: - // Data - CountPtrType pCount_; - }; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class COMRefCounted -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Adapts COM intrusive reference counting to OwnershipPolicy-specific syntax -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -class COMRefCounted -{ -public: - COMRefCounted() - {} - - template <class U> - COMRefCounted(const COMRefCounted<U>&) - {} - - 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; - } - - enum { destructiveCopy = false }; - - static void Swap(COMRefCounted&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct DeepCopy -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Implements deep copy semantics, assumes existence of a Clone() member -/// function of the pointee type -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct DeepCopy -{ - DeepCopy() - {} - - template <class P1> - DeepCopy(const DeepCopy<P1>&) - {} - - static P Clone(const P& val) - { return val->Clone(); } - - static bool Release(const P&) - { return true; } - - static void Swap(DeepCopy&) - {} - - enum { destructiveCopy = false }; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class RefLinked -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Implements reference linking -//////////////////////////////////////////////////////////////////////////////// - -namespace Private -{ -class LOKI_EXPORT RefLinkedBase -{ -public: - RefLinkedBase() - { prev_ = next_ = this; } - - RefLinkedBase(const RefLinkedBase& rhs); - - bool Release(); - - void Swap(RefLinkedBase& rhs); - - bool Merge( RefLinkedBase& rhs ); - - 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; - - mutable const RefLinkedBase* prev_; - mutable const RefLinkedBase* next_; -}; -} - -template <class P> -class RefLinked : public Private::RefLinkedBase -{ -public: - RefLinked() - {} - - template <class P1> - RefLinked(const RefLinked<P1>& rhs) - : Private::RefLinkedBase(rhs) - {} - - static P Clone(const P& val) - { return val; } - - bool Release(const P&) - { return Private::RefLinkedBase::Release(); } - - template < class P1 > - bool Merge( RefLinked< P1 > & rhs ) - { - return Private::RefLinkedBase::Merge( rhs ); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class DestructiveCopy -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Implements destructive copy semantics (a la std::auto_ptr) -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -class DestructiveCopy -{ -public: - DestructiveCopy() - {} - - template <class P1> - DestructiveCopy(const DestructiveCopy<P1>&) - {} - - template <class P1> - static P Clone(P1& val) - { - P result(val); - val = P1(); - return result; - } - - static bool Release(const P&) - { return true; } - - static void Swap(DestructiveCopy&) - {} - - enum { destructiveCopy = true }; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class NoCopy -/// -/// \ingroup SmartPointerOwnershipGroup -/// Implementation of the OwnershipPolicy used by SmartPtr -/// Implements a policy that doesn't allow copying objects -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -class NoCopy -{ -public: - NoCopy() - {} - - 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; - - LOKI_STATIC_CHECK(DependedFalse, This_Policy_Disallows_Value_Copying); - } - - static bool Release(const P&) - { return true; } - - static void Swap(NoCopy&) - {} - - enum { destructiveCopy = false }; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct AllowConversion -/// -/// \ingroup SmartPointerConversionGroup -/// Implementation of the ConversionPolicy used by SmartPtr -/// Allows implicit conversion from SmartPtr to the pointee type -//////////////////////////////////////////////////////////////////////////////// - -struct AllowConversion -{ - enum { allow = true }; - - void Swap(AllowConversion&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct DisallowConversion -/// -/// \ingroup SmartPointerConversionGroup -/// Implementation of the ConversionPolicy used by SmartPtr -/// Does not allow implicit conversion from SmartPtr to the pointee type -/// You can initialize a DisallowConversion with an AllowConversion -//////////////////////////////////////////////////////////////////////////////// - -struct DisallowConversion -{ - DisallowConversion() - {} - - DisallowConversion(const AllowConversion&) - {} - - enum { allow = false }; - - void Swap(DisallowConversion&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct NoCheck -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Well, it's clear what it does :o) -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct NoCheck -{ - NoCheck() - {} - - template <class P1> - NoCheck(const NoCheck<P1>&) - {} - - static void OnDefault(const P&) - {} - - static void OnInit(const P&) - {} - - static void OnDereference(const P&) - {} - - static void Swap(NoCheck&) - {} -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \struct AssertCheck -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Checks the pointer before dereference -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct AssertCheck -{ - AssertCheck() - {} - - template <class P1> - AssertCheck(const AssertCheck<P1>&) - {} - - template <class P1> - AssertCheck(const NoCheck<P1>&) - {} - - static void OnDefault(const P&) - {} - - static void OnInit(const P&) - {} - - static void OnDereference(P val) - { assert(val); (void)val; } - - static void Swap(AssertCheck&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct AssertCheckStrict -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Checks the pointer against zero upon initialization and before dereference -/// You can initialize an AssertCheckStrict with an AssertCheck -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct AssertCheckStrict -{ - AssertCheckStrict() - {} - - template <class U> - AssertCheckStrict(const AssertCheckStrict<U>&) - {} - - template <class U> - AssertCheckStrict(const AssertCheck<U>&) - {} - - template <class P1> - AssertCheckStrict(const NoCheck<P1>&) - {} - - static void OnDefault(P val) - { assert(val); } - - static void OnInit(P val) - { assert(val); } - - static void OnDereference(P val) - { assert(val); } - - static void Swap(AssertCheckStrict&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct NullPointerException -/// -/// \ingroup SmartPointerGroup -/// 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 RejectNullStatic -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Checks the pointer upon initialization and before dereference -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct RejectNullStatic -{ - RejectNullStatic() - {} - - template <class P1> - RejectNullStatic(const RejectNullStatic<P1>&) - {} - - template <class P1> - RejectNullStatic(const NoCheck<P1>&) - {} - - template <class P1> - RejectNullStatic(const AssertCheck<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; - - LOKI_STATIC_CHECK(DependedFalse, ERROR_This_Policy_Does_Not_Allow_Default_Initialization); - } - - static void OnInit(const P& val) - { if (!val) throw NullPointerException(); } - - static void OnDereference(const P& val) - { if (!val) throw NullPointerException(); } - - static void Swap(RejectNullStatic&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct RejectNull -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Checks the pointer before dereference -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct RejectNull -{ - RejectNull() - {} - - template <class P1> - RejectNull(const RejectNull<P1>&) - {} - - static void OnInit(P) - {} - - static void OnDefault(P) - {} - - void OnDereference(P val) - { if (!val) throw NullPointerException(); } - - void OnDereference(P val) const - { if (!val) throw NullPointerException(); } - - void Swap(RejectNull&) - {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \struct RejectNullStrict -/// -/// \ingroup SmartPointerCheckingGroup -/// Implementation of the CheckingPolicy used by SmartPtr -/// Checks the pointer upon initialization and before dereference -//////////////////////////////////////////////////////////////////////////////// - -template <class P> -struct RejectNullStrict -{ - RejectNullStrict() - {} - - template <class P1> - RejectNullStrict(const RejectNullStrict<P1>&) - {} - - template <class P1> - RejectNullStrict(const RejectNull<P1>&) - {} - - static void OnInit(P val) - { if (!val) throw NullPointerException(); } - - void OnDereference(P val) - { OnInit(val); } - - void OnDereference(P val) const - { OnInit(val); } - - void Swap(RejectNullStrict&) - {} -}; - - -//////////////////////////////////////////////////////////////////////////////// -// class template SmartPtr (declaration) -// 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; - -//////////////////////////////////////////////////////////////////////////////// -// class template SmartPtrDef (definition) -// this class added to unify the usage of SmartPtr -// instead of writing SmartPtr<T,OP,CP,KP,SP> write SmartPtrDef<T,OP,CP,KP,SP>::type -//////////////////////////////////////////////////////////////////////////////// - -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 - < - T, - OwnershipPolicy, - ConversionPolicy, - CheckingPolicy, - StoragePolicy, - ConstnessPolicy - > - type; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class SmartPtr -/// -/// \ingroup SmartPointerGroup -/// -/// \param OwnershipPolicy default = RefCounted, -/// \param ConversionPolicy default = DisallowConversion, -/// \param CheckingPolicy default = AssertCheck, -/// \param StoragePolicy default = DefaultSPStorage -/// \param ConstnessPolicy default = LOKI_DEFAULT_CONSTNESS -/// -/// \par IMPORTANT NOTE -/// Due to threading issues, the OwnershipPolicy has been changed as follows: -/// -/// - Release() returns a boolean saying if that was the last release -/// so the pointer can be deleted by the StoragePolicy -/// - 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; - -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 Select<OP::destructiveCopy, SmartPtr, const SmartPtr>::Result - CopyArg; - -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; -#else - typedef const StoredType& ImplicitArg; - typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg; -#endif - -public: - - SmartPtr() - { - KP::OnDefault(GetImpl(*this)); - } - - explicit - SmartPtr(ExplicitArg 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)); - } - - 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) - : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - { - GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); - } - - SmartPtr(RefToValue<SmartPtr> rhs) - : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - {} - - operator RefToValue<SmartPtr>() - { return RefToValue<SmartPtr>(*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=(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); - } - - ~SmartPtr() - { - if (OP::Release(GetImpl(*static_cast<SP*>(this)))) - { - 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(); - } - - 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); -#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 ) - { - if ( GetImpl( *this ) != GetImpl( rhs ) ) - { - return false; - } - return OP::template Merge( rhs ); - } - - PointerType operator->() - { - 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*(); - } - - 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 ) ); - } - - // 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 ) ); - } - - // 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 ) ); - } - -private: - // Helper for enabling 'if (sp)' - struct Tester - { - Tester(int) {} - void dummy() {} - }; - - typedef void (Tester::*unspecified_boolean_type_)(); - - typedef typename Select<CP::allow, Tester, unspecified_boolean_type_>::Result - unspecified_boolean_type; - -public: - // enable 'if (sp)' - operator unspecified_boolean_type() const - { - return !*this ? 0 : &Tester::dummy; - } - -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 -//////////////////////////////////////////////////////////////////////////////// - -#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 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 - -//////////////////////////////////////////////////////////////////////////////// -// free comparison operators for class template SmartPtr -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -/// 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 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; } - -//////////////////////////////////////////////////////////////////////////////// -/// 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); } - -//////////////////////////////////////////////////////////////////////////////// -/// 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; } - -//////////////////////////////////////////////////////////////////////////////// -/// 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 ); -} - -//////////////////////////////////////////////////////////////////////////////// -/// 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 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// 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; } - -//////////////////////////////////////////////////////////////////////////////// -/// 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; } - -//////////////////////////////////////////////////////////////////////////////// -/// 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); } - -//////////////////////////////////////////////////////////////////////////////// -/// 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); } - -//////////////////////////////////////////////////////////////////////////////// -/// 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); } - -//////////////////////////////////////////////////////////////////////////////// -/// 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); } - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -/// specialization of std::less for SmartPtr -/// \ingroup SmartPointerGroup -//////////////////////////////////////////////////////////////////////////////// - -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 > > - : 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)); } -}; -} - -#endif // end file guardian - diff --git a/shared/loki/StrongPtr.h b/shared/loki/StrongPtr.h deleted file mode 100644 index 868eb48f..00000000 --- a/shared/loki/StrongPtr.h +++ /dev/null @@ -1,1697 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2006 Rich 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 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 warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_STRONG_PTR_INC_ -#define LOKI_STRONG_PTR_INC_ - -// $Id: StrongPtr.h 914 2008-12-19 00:39:29Z rich_sposato $ - - -#include <loki/SmartPtr.h> -#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING) -#include <loki/Threads.h> -#endif - - -//////////////////////////////////////////////////////////////////////////////// -/// -/// \par Terminology -/// These terms are used within this file's comments. -/// -# StrongPtr : Class used to implement both strong and weak pointers. The -/// second template parameter determines if a StrongPtr is weak or strong. -/// -# Strong pointer : A pointer that claims ownership of a shared object. -/// When the last strong copointer dies, the object is destroyed even if -/// there are weak copointers. -/// -# Weak pointer : A pointer that does not own the shared object it points -/// to. It only destroys the shared object if there no strong copointers -/// exist when it dies. -/// -# Copointers : All the pointers that refer to the same shared object. -/// The copointers must have the same ownership policy, but the other -/// policies may be different. -/// -# Pointee : The shared object. -/// -/// \par OwnershipPolicy -/// The ownership policy has the pointer to the actual object, and it also -/// keeps track of the strong and weak copointers so that it can know if any -/// strong copointers remain. The plain pointer it maintains is stored as a -/// void pointer, which allows the ownership policy classes to be monolithic -/// classes instead of template classes. As monolithic classes, they reduce -/// amount of code-bloat. -/// -/// \par Writing Your Own OwnershipPolicy -/// If you write your own policy, you must implement these 12 functions: -/// -# explicit YourPolicy( bool strong ) -/// -# YourPolicy( void * p, bool strong ) -/// -# YourPolicy( const YourPolicy & rhs, bool strong ) -/// -# bool Release( bool strong ) -/// -# void Increment( bool strong ) -/// -# bool Decrement( bool strong ) -/// -# bool HasStrongPointer( void ) const -/// -# void Swap( YourPolicy & rhs ) -/// -# void SetPointer( void * p ) -/// -# void ZapPointer( void ) -/// -# void * GetPointer( void ) const -/// -# void * & GetPointerRef( void ) const -/// It is strongly recommended that all 12 of these functions be protected -/// instead of public. These two functions are optional for single-threaded -/// policies, but required for multi-threaded policies: -/// -# void Lock( void ) const -/// -# void Unlock( void ) const -/// This function is entirely optional: -/// -# bool Merge( TwoRefLinks & rhs ) -/// -/// \par DeletePolicy -/// The delete policy provides a mechanism to destroy an object and a default -/// value for an uninitialized pointer. You can override this policy with -/// your own when using the Singleton, NullObject, or Prototype design -/// patterns. -/// -/// \par Writing Your Own DeletePolicy -/// If you write your own policy, you must implement these 3 functions: -/// -# void static Delete( const P * p ) -/// -# static P * Default( void ) -/// -# void Swap( YourResetPolicy & ) -/// -/// \par ResetPolicy -/// A reset policy tells the ReleaseAll and ResetAll functions whether they -/// should release or reset the StrongPtr copointers. These functions do -/// not affect just one StrongPtr, but all copointers. That is unlike -/// SmartPtr where the Release and Reset functions only affect 1 SmartPtr, -/// and leave all copointers untouched. A useful trick you can do with the -/// ResetPolicy is to not allow reset when a strong pointer exists, and then -/// use the NoCheck policy for all strong pointers. The reset policy -/// guarantees the strong pointers always have a valid pointee, so checking -/// is not required; but weak pointers may still require checking. -/// -/// \par Writing Your Own ResetPolicy -/// If you write your own policy, you must implement these 2 functions: -/// -# bool OnReleaseAll( bool ) const -/// -# bool OnResetAll( bool ) const -/// The bool parameter means that this was called with a strong pointer or -/// one of its copointers is strong. The return value means the pointer -/// can be reset or released. -/// -/// \defgroup StrongPointerOwnershipGroup StrongPtr Ownership policies -/// \ingroup SmartPointerGroup -/// \defgroup StrongPointerDeleteGroup Delete policies -/// \ingroup SmartPointerGroup -/// \defgroup StrongPointerResetGroup Reset policies -/// \ingroup SmartPointerGroup -//////////////////////////////////////////////////////////////////////////////// - - -namespace Loki -{ - - -//////////////////////////////////////////////////////////////////////////////// -/// \class DeleteUsingFree -/// -/// \ingroup StrongPointerDeleteGroup -/// Implementation of the DeletePolicy used by StrongPtr. Uses explicit call -/// to T's destructor followed by call to free. This policy is useful for -/// managing the lifetime of pointers to structs returned by C functions. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -class DeleteUsingFree -{ -public: - inline void static Delete( const P* p ) - { - if ( 0 != p ) - { - p->~P(); - ::free( p ); - } - } - - /// Provides default value to initialize the pointer - inline static P* Default( void ) - { - return 0; - } - - inline void Swap( DeleteUsingFree& ) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class DeleteNothing -/// -/// \ingroup StrongPointerDeleteGroup -/// Implementation of the DeletePolicy used by StrongPtr. This will never -/// delete anything. You can use this policy with pointers to an undefined -/// type or a pure interface class with a protected destructor. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -class DeleteNothing -{ -public: - inline static void Delete( const P* ) - { - // Do nothing at all! - } - - inline static P* Default( void ) - { - return 0; - } - - inline void Swap( DeleteNothing& ) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class DeleteSingle -/// -/// \ingroup StrongPointerDeleteGroup -/// Implementation of the DeletePolicy used by StrongPtr. This deletes just -/// one shared object. This is the default class for the DeletePolicy. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -class DeleteSingle -{ -public: - 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. - Please don't use this policy with incomplete types; you may want to - use DeleteNothing instead. - */ - typedef char Type_Must_Be_Defined[ sizeof(P) ? 1 : -1 ]; - delete p; - } - - inline static P* Default( void ) - { - return 0; - } - - inline void Swap( DeleteSingle& ) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class DeleteArray -/// -/// \ingroup StrongPointerDeleteGroup -/// Implementation of the DeletePolicy used by StrongPtr. This deletes an -/// array of shared objects. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -class DeleteArray -{ -public: - 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. - Please don't use this policy with incomplete types; you may want to - use DeleteNothing instead. - */ - typedef char Type_Must_Be_Defined[ sizeof(P) ? 1 : -1 ]; - delete [] p; - } - - inline static P* Default( void ) - { - return 0; - } - - inline void Swap( DeleteArray& ) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class CantResetWithStrong -/// -/// \ingroup StrongPointerResetGroup -/// Implementation of the ResetPolicy used by StrongPtr. This is the default -/// ResetPolicy for StrongPtr. It forbids reset and release only if a strong -/// copointer exists. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -struct CantResetWithStrong -{ - inline bool OnReleaseAll( bool hasStrongPtr ) const - { - return ! hasStrongPtr; - } - - inline bool OnResetAll( bool hasStrongPtr ) const - { - return ! hasStrongPtr; - } -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class AllowReset -/// -/// \ingroup StrongPointerResetGroup -/// Implementation of the ResetPolicy used by StrongPtr. It allows reset and -/// release under any circumstance. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -struct AllowReset -{ - inline bool OnReleaseAll( bool ) const - { - return true; - } - inline bool OnResetAll( bool ) const - { - return true; - } -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class NeverReset -/// -/// \ingroup StrongPointerResetGroup -/// Implementation of the ResetPolicy used by StrongPtr. It forbids reset and -/// release under any circumstance. -//////////////////////////////////////////////////////////////////////////////// - -template < class P > -struct NeverReset -{ - inline bool OnReleaseAll( bool ) const - { - return false; - } - inline bool OnResetAll( bool ) const - { - return false; - } -}; - -// ---------------------------------------------------------------------------- - -namespace Private -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class TwoRefCountInfo -/// -/// \ingroup StrongPointerOwnershipGroup -/// Implementation detail for reference counting strong and weak pointers. -/// It maintains a void pointer and 2 reference counts. Since it is just a -/// class for managing implementation details, it is not intended to be used -/// directly - which is why it is in a private namespace. Each instance is a -/// shared resource for all copointers, and there should be only one of these -/// for each set of copointers. This class is small, trivial, and inline. -//////////////////////////////////////////////////////////////////////////////// - -class LOKI_EXPORT TwoRefCountInfo -{ -public: - - inline explicit TwoRefCountInfo( bool strong ) - : m_pointer( 0 ) - , m_strongCount( strong ? 1 : 0 ) - , m_weakCount( strong ? 0 : 1 ) - { - } - - inline TwoRefCountInfo( void* p, bool strong ) - : m_pointer( p ) - , m_strongCount( strong ? 1 : 0 ) - , m_weakCount( strong ? 0 : 1 ) - { - } - - inline ~TwoRefCountInfo( void ) - { - assert( 0 == m_strongCount ); - assert( 0 == m_weakCount ); - } - - inline bool HasStrongPointer( void ) const - { - return ( 0 < m_strongCount ); - } - - inline bool HasWeakPointer( void ) const - { - return ( 0 < m_weakCount ); - } - - inline void IncStrongCount( void ) - { - ++m_strongCount; - } - - inline void IncWeakCount( void ) - { - ++m_weakCount; - } - - inline bool DecStrongCount( void ) - { - assert( 0 < m_strongCount ); - --m_strongCount; - const bool isZero = ( 0 == m_strongCount ); - return isZero; - } - - inline void DecWeakCount( void ) - { - assert( 0 < m_weakCount ); - --m_weakCount; - } - - inline void ZapPointer( void ) - { - m_pointer = 0; - } - - void SetPointer( void* p ) - { - m_pointer = p; - } - - inline void* GetPointer( void ) const - { - return m_pointer; - } - - inline void*& GetPointerRef( void ) const - { - return const_cast< void *& >( m_pointer ); - } - -private: - /// Copy-constructor not implemented. - TwoRefCountInfo( const TwoRefCountInfo& ); - /// Copy-assignment operator not implemented. - TwoRefCountInfo& operator = ( const TwoRefCountInfo& ); - - void* m_pointer; - unsigned int m_strongCount; - unsigned int m_weakCount; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class LockableTwoRefCountInfo -/// -/// \ingroup StrongPointerOwnershipGroup -/// Implementation detail for thread-safe reference counting for strong and -/// weak pointers. It uses TwoRefCountInfo to manage the pointer and counts. -/// All this does is provide a thread safety mechanism. Since it is just a -/// class for managing implementation details, it is not intended to be used -/// directly - which is why it is in a private namespace. Each instance is a -/// shared resource for all copointers, and there should be only one of these -/// for each set of copointers. This class is small, trivial, and inline. -/// -/// \note This class is not designed for use with a single-threaded model. -/// Tests using a single-threaded model will not run properly, but tests in a -/// multi-threaded model with either class-level-locking or object-level-locking -/// do run properly. -//////////////////////////////////////////////////////////////////////////////// - -#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING) - -class LOKI_EXPORT LockableTwoRefCountInfo - : private Loki::Private::TwoRefCountInfo -{ -public: - - inline explicit LockableTwoRefCountInfo( bool strong ) - : TwoRefCountInfo( strong ) - , m_Mutex() - { - } - - LockableTwoRefCountInfo( void* p, bool strong ) - : TwoRefCountInfo( p, strong ) - , m_Mutex() - { - } - - inline ~LockableTwoRefCountInfo( void ) - { - } - - inline void Lock( void ) const - { - m_Mutex.Lock(); - } - - inline void Unlock( void ) const - { - m_Mutex.Unlock(); - } - - inline bool HasStrongPointer( void ) const - { - m_Mutex.Lock(); - const bool has = TwoRefCountInfo::HasStrongPointer(); - m_Mutex.Unlock(); - return has; - } - - inline bool HasWeakPointer( void ) const - { - m_Mutex.Lock(); - const bool has = TwoRefCountInfo::HasWeakPointer(); - m_Mutex.Unlock(); - return has; - } - - inline void IncStrongCount( void ) - { - m_Mutex.Lock(); - TwoRefCountInfo::IncStrongCount(); - m_Mutex.Unlock(); - } - - inline void IncWeakCount( void ) - { - m_Mutex.Lock(); - TwoRefCountInfo::IncWeakCount(); - m_Mutex.Unlock(); - } - - inline bool DecStrongCount( void ) - { - m_Mutex.Lock(); - const bool isZero = TwoRefCountInfo::DecStrongCount(); - m_Mutex.Unlock(); - return isZero; - } - - inline void DecWeakCount( void ) - { - m_Mutex.Lock(); - TwoRefCountInfo::DecWeakCount(); - m_Mutex.Unlock(); - } - - inline void ZapPointer( void ) - { - m_Mutex.Lock(); - TwoRefCountInfo::ZapPointer(); - m_Mutex.Unlock(); - } - - void SetPointer( void* p ) - { - m_Mutex.Lock(); - TwoRefCountInfo::SetPointer( p ); - m_Mutex.Unlock(); - } - - inline void* GetPointer( void ) const - { - return TwoRefCountInfo::GetPointer(); - } - - inline void*& GetPointerRef( void ) const - { - return TwoRefCountInfo::GetPointerRef(); - } - -private: - /// Default constructor is not available. - LockableTwoRefCountInfo( void ); - /// Copy constructor is not available. - LockableTwoRefCountInfo( const LockableTwoRefCountInfo& ); - /// Copy-assignment operator is not available. - LockableTwoRefCountInfo& operator = ( const LockableTwoRefCountInfo& ); - - mutable LOKI_DEFAULT_MUTEX m_Mutex; -}; - -#endif // if object-level-locking or class-level-locking - -} // end namespace Private - -//////////////////////////////////////////////////////////////////////////////// -/// \class TwoRefCounts -/// -/// \ingroup StrongPointerOwnershipGroup -/// This implementation of StrongPtr's OwnershipPolicy uses a pointer to a -/// shared instance of TwoRefCountInfo. This is the default policy for -/// OwnershipPolicy. Some functions are trivial enough to be inline, while -/// others are implemented elsewhere. It is not thread safe, and is intended -/// for single-threaded environments. -//////////////////////////////////////////////////////////////////////////////// - -class LOKI_EXPORT TwoRefCounts -{ -protected: - - explicit TwoRefCounts( bool strong ); - - TwoRefCounts( const void* p, bool strong ); - - TwoRefCounts( const TwoRefCounts& rhs, bool strong ) : - m_counts( rhs.m_counts ) - { - Increment( strong ); - } - - /** The destructor does not need to do anything since the call to - ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which - this dtor would have done. - */ - inline ~TwoRefCounts( void ) {} - - inline bool Release( bool strong ) - { - return Decrement( strong ); - } - - bool HasStrongPointer( void ) const - { - return m_counts->HasStrongPointer(); - } - - void Swap( TwoRefCounts& rhs ); - - void SetPointer( void* p ) - { - m_counts->SetPointer( p ); - } - - void ZapPointer( void ); - - inline void*& GetPointerRef( void ) const - { - return m_counts->GetPointerRef(); - } - - inline void* GetPointer( void ) const - { - return m_counts->GetPointer(); - } - -private: - TwoRefCounts( void ); - TwoRefCounts& operator = ( const TwoRefCounts& ); - - void Increment( bool strong ); - - bool Decrement( bool strong ); - - /// Pointer to all shared data. - Loki::Private::TwoRefCountInfo* m_counts; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class LockableTwoRefCounts -/// -/// \ingroup StrongPointerOwnershipGroup -/// This implementation of StrongPtr's OwnershipPolicy uses a pointer to a -/// shared instance of LockableTwoRefCountInfo. It behaves very similarly to -/// TwoRefCounts, except that it provides thread-safety. Some functions are -/// trivial enough to be inline, while others are implemented elsewhere. -/// -/// \note This class is not designed for use with a single-threaded model. -/// Tests using a single-threaded model will not run properly, but tests in a -/// multi-threaded model with either class-level-locking or object-level-locking -/// do run properly. -//////////////////////////////////////////////////////////////////////////////// - -#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING) - -class LOKI_EXPORT LockableTwoRefCounts -{ - typedef SmallValueObject< ::Loki::ClassLevelLockable > ThreadSafePointerAllocator; - -protected: - - explicit LockableTwoRefCounts( bool strong ) - : m_counts( NULL ) - { - 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 ) - : m_counts( NULL ) - { - void* temp = ThreadSafePointerAllocator::operator new( - sizeof(Loki::Private::LockableTwoRefCountInfo) ); -#ifdef DO_EXTRA_LOKI_TESTS - assert( temp != 0 ); -#endif - void* p2 = const_cast< void* >( p ); - m_counts = new ( temp ) - Loki::Private::LockableTwoRefCountInfo( p2, strong ); - } - - LockableTwoRefCounts( const LockableTwoRefCounts& rhs, bool strong ) : - m_counts( rhs.m_counts ) - { - Increment( strong ); - } - - /** The destructor does not need to do anything since the call to - ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which - this dtor would have done. - */ - inline ~LockableTwoRefCounts( void ) {} - - inline void Lock( void ) const - { - m_counts->Lock(); - } - - inline void Unlock( void ) const - { - m_counts->Unlock(); - } - - inline bool Release( bool strong ) - { - return Decrement( strong ); - } - - void Increment( bool strong ) - { - if ( strong ) - { - m_counts->IncStrongCount(); - } - else - { - m_counts->IncWeakCount(); - } - } - - bool Decrement( bool strong ) - { - bool noStrongPointers = false; - if ( strong ) - { - noStrongPointers = m_counts->DecStrongCount(); - } - else - { - m_counts->DecWeakCount(); - noStrongPointers = !m_counts->HasStrongPointer(); - } - return noStrongPointers; - } - - bool HasStrongPointer( void ) const - { - return m_counts->HasStrongPointer(); - } - - void Swap( LockableTwoRefCounts& rhs ) - { - std::swap( m_counts, rhs.m_counts ); - } - - void SetPointer( void* p ) - { - m_counts->SetPointer( p ); - } - - void ZapPointer( void ) - { -#ifdef DO_EXTRA_LOKI_TESTS - assert( !m_counts->HasStrongPointer() ); -#endif - if ( m_counts->HasWeakPointer() ) - { - m_counts->ZapPointer(); - } - else - { - ThreadSafePointerAllocator::operator delete ( m_counts, - sizeof(Loki::Private::LockableTwoRefCountInfo) ); - m_counts = NULL; - } - } - - inline void* GetPointer( void ) const - { - return m_counts->GetPointer(); - } - - inline void*& GetPointerRef( void ) const - { - return m_counts->GetPointerRef(); - } - -private: - LockableTwoRefCounts( void ); - LockableTwoRefCounts& operator = ( const LockableTwoRefCounts& ); - - /// Pointer to all shared data. - Loki::Private::LockableTwoRefCountInfo* m_counts; -}; - -#endif // if object-level-locking or class-level-locking - -//////////////////////////////////////////////////////////////////////////////// -/// \class TwoRefLinks -/// -/// \ingroup StrongPointerOwnershipGroup -/// This implementation of StrongPtr's OwnershipPolicy uses a doubly-linked -/// cycle of copointers to a shared object. Some functions are trivial enough -/// to be inline, while others are implemented in elsewhere. It is not thread -/// safe, and is intended for single-threaded environments. -//////////////////////////////////////////////////////////////////////////////// - -class LOKI_EXPORT TwoRefLinks -{ -protected: - - inline explicit TwoRefLinks( bool strong ) - : m_pointer( 0 ) - , m_strong( strong ) - { - m_prev = m_next = this; - } - - TwoRefLinks( const void* p, bool strong ); - - TwoRefLinks( const TwoRefLinks& rhs, bool strong ); - - bool Release( bool strong ); - - void Swap( TwoRefLinks& rhs ); - - bool Merge( TwoRefLinks& rhs ); - - bool HasStrongPointer( void ) const; - - inline void ZapPointer( void ) - { - ZapAllNodes(); - } - - void SetPointer( void* p ); - - inline void* GetPointer( void ) const - { - return m_pointer; - } - - inline void*& GetPointerRef( void ) const - { - return const_cast< void *& >( m_pointer ); - } - -private: - static unsigned int CountPrevCycle( const TwoRefLinks* pThis ); - static unsigned int CountNextCycle( const TwoRefLinks* pThis ); - - /// Not implemented. - TwoRefLinks( void ); - /// Not implemented. - TwoRefLinks& operator = ( const TwoRefLinks& ); - - 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; - const bool m_strong; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class StrongPtr -/// -/// \ingroup SmartPointerGroup -/// -/// \param Strong default = true, -/// \param OwnershipPolicy default = TwoRefCounts, -/// \param ConversionPolicy default = DisallowConversion, -/// \param CheckingPolicy default = AssertCheck, -/// \param ResetPolicy default = CantResetWithStrong, -/// \param DeletePolicy default = DeleteSingle -/// \param ConstnessPolicy default = LOKI_DEFAULT_CONSTNESS -//////////////////////////////////////////////////////////////////////////////// - -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 - > -class StrongPtr - : public OwnershipPolicy - , public ConversionPolicy - , public CheckingPolicy< T* > - , public ResetPolicy< T > - , public DeletePolicy< T > -{ - typedef ConversionPolicy CP; - typedef CheckingPolicy< T* > KP; - typedef ResetPolicy< T > RP; - typedef DeletePolicy< T > DP; - -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 typename ConstnessPolicy< T >::Type* ConstPointerType; - typedef typename ConstnessPolicy< T >::Type& ConstReferenceType; - -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; -#else - typedef const StoredType& ImplicitArg; - typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg; -#endif - -public: - - StrongPtr( void ) : OP( Strong ) - { - KP::OnDefault( GetPointer() ); - } - - explicit StrongPtr( ExplicitArg p ) : OP( p, Strong ) - { - KP::OnInit( GetPointer() ); - } - - StrongPtr( ImplicitArg p ) : OP( p, Strong ) - { - KP::OnInit( GetPointer() ); - } - - 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 - > - StrongPtr( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) - : OP( rhs, Strong ) - { - } - - 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( - StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) - : OP( rhs, Strong ) - { - } - - StrongPtr( RefToValue< StrongPtr > rhs ) - : OP( rhs, Strong ), KP( rhs ), CP( rhs ), DP( rhs ) - { - } - - operator RefToValue< StrongPtr >( void ) - { - return RefToValue< StrongPtr >( *this ); - } - - StrongPtr& operator = ( const StrongPtr& rhs ) - { - if ( GetPointer() != rhs.GetPointer() ) - { - StrongPtr temp( rhs ); - temp.Swap( *this ); - } - return *this; - } - - StrongPtr& operator = ( T* p ) - { - if ( GetPointer() != p ) - { - StrongPtr temp( p ); - Swap( temp ); - } - return *this; - } - - 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 = ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) - { - if ( !rhs.Equals( GetPointer() ) ) - { - StrongPtr temp( rhs ); - temp.Swap( *this ); - } - return *this; - } - - bool IsStrong( void ) const - { - return Strong; - } - - void Swap( StrongPtr& rhs ) - { - OP::Swap( rhs ); - CP::Swap( rhs ); - KP::Swap( rhs ); - DP::Swap( rhs ); - } - - ~StrongPtr() - { - if ( OP::Release( Strong ) ) - { - // Must zap the pointer before deleteing the object. Otherwise a - // cycle of weak pointers will lead to recursion, which leads to - // 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(); - OP::ZapPointer(); - if ( p != 0 ) - { - DP::Delete( p ); - } - } - } - -#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 ) - { - if ( !sp.RP::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) ) - { - return false; - } - p = sp.GetPointer(); - sp.OP::SetPointer( sp.DP::Default() ); - return true; - } - - friend bool ResetAll( StrongPtr& sp, - typename StrongPtr::StoredType p ) - { - if ( sp.OP::GetPointer() == p ) - { - return true; - } - if ( !sp.RP::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) ) - { - return false; - } - sp.DP::Delete( sp.GetPointer() ); - sp.OP::SetPointer( p ); - return true; - } - -#else - - 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 - > - 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 ); - - - 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 - > - 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 ); - -#endif - - - /** Merges ownership of two StrongPtr's that point to same shared object - but are not copointers. Requires Merge function in OwnershipPolicy. - \return True for success, false if not pointer to same object. - */ - 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 - > - bool Merge( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) - { - if ( OP::GetPointer() != rhs.OP::GetPointer() ) - { - return false; - } - return OP::Merge( rhs ); - } - - /** Locks StrongPtr so other threads can't affect pointer. Requires the - OwnershipPolicy to have Lock function. - */ - void Lock( void ) - { - OP::Lock(); - } - - /** Unlocks StrongPtr so other threads can affect pointer. Requires the - OwnershipPolicy to have Unlock function. - */ - void Unlock( void ) - { - OP::Unlock(); - } - - PointerType operator -> () - { - KP::OnDereference( GetPointer() ); - return GetPointer(); - } - - ConstPointerType operator -> () const - { - KP::OnDereference( GetPointer() ); - return GetPointer(); - } - - ReferenceType operator * () - { - KP::OnDereference( GetPointer() ); - return * GetPointer(); - } - - ConstReferenceType operator * () const - { - KP::OnDereference( GetPointer() ); - return * GetPointer(); - } - - /// Helper function which can be called to avoid exposing GetPointer function. - template < class T1 > - 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 - { - return ( GetPointer() < p ); - } - - /// Helper function which can be called to avoid exposing GetPointer function. - template < class T1 > - bool GreaterThan( const T1* p ) const - { - return ( GetPointer() > p ); - } - - /// 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 - > - bool operator == ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return ( rhs.Equals( GetPointer() ) ); - } - - /// 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 - > - bool operator != ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return !( rhs.Equals( GetPointer() ) ); - } - - /// 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 - > - bool operator < ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return ( rhs.GreaterThan( GetPointer() ) ); - } - - /// 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 - > - inline bool operator > ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return ( rhs.LessThan( GetPointer() ) ); - } - - /// 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 - > - inline bool operator <= ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return !( rhs.LessThan( GetPointer() ) ); - } - - /// 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 - > - inline bool operator >= ( - const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const - { - return !( rhs.GreaterThan( GetPointer() ) ); - } - - inline bool operator ! () const // Enables "if ( !sp ) ..." - { - return ( 0 == OP::GetPointer() ); - } - -protected: - - inline PointerType GetPointer( void ) - { - return reinterpret_cast< PointerType >( OP::GetPointer() ); - } - - inline ConstPointerType GetPointer( void ) const - { - return reinterpret_cast< ConstPointerType >( OP::GetPointer() ); - } - -private: - - inline ReferenceType GetPointerRef( void ) - { - return reinterpret_cast< ReferenceType >( OP::GetPointerRef() ); - } - - inline ConstReferenceType GetPointerRef( void ) const - { - return reinterpret_cast< ConstReferenceType >( OP::GetPointerRef() ); - } - - // Helper for enabling 'if (sp)' - struct Tester - { - Tester(int) {} - void dummy() {} - }; - - typedef void (Tester::*unspecified_boolean_type_)(); - - typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result - unspecified_boolean_type; - -public: - // enable 'if (sp)' - operator unspecified_boolean_type() const - { - return !*this ? 0 : &Tester::dummy; - } - -private: - // Helper for disallowing automatic conversion - struct Insipid - { - Insipid(PointerType) {} - }; - - typedef typename Select< CP::allow, PointerType, Insipid >::Result - AutomaticConversionResult; - -public: - operator AutomaticConversionResult() const - { - return GetPointer(); - } - -}; - -// ---------------------------------------------------------------------------- - -// friend functions - -#ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND - -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 - > -bool ReleaseAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp, - 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; -} - -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 - > -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 ) - { - 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 - - -// free comparison operators for class template StrongPtr - -/// operator== for lhs = StrongPtr, rhs = raw pointer -/// \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 == ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return ( lhs.Equals( rhs ) ); -} - -/// operator== for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return ( rhs.Equals( lhs ) ); -} - -/// operator!= for lhs = StrongPtr, rhs = raw pointer -/// \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 != ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return !( lhs.Equals( rhs ) ); -} - -/// operator!= for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return !( rhs.Equals( lhs ) ); -} - -/// operator< for lhs = StrongPtr, rhs = raw pointer -/// \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 < ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return ( lhs.LessThan( rhs ) ); -} - -/// operator< for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return ( rhs.GreaterThan( lhs ) ); -} - -// operator> for lhs = StrongPtr, rhs = raw pointer -/// \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 > ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return ( lhs.GreaterThan( rhs ) ); -} - -/// operator> for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return ( rhs.LessThan( lhs ) ); -} - -/// operator<= for lhs = StrongPtr, rhs = raw pointer -/// \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 <= ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return !( lhs.GreaterThan( rhs ) ); -} - -/// operator<= for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return !( rhs.LessThan( lhs ) ); -} - -/// operator>= for lhs = StrongPtr, rhs = raw pointer -/// \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 >= ( - const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs ) -{ - return !( lhs.LessThan( rhs ) ); -} - -/// operator>= for lhs = raw pointer, rhs = StrongPtr -/// \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 ) -{ - return !( rhs.GreaterThan( lhs ) ); -} - -} // namespace Loki - -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 > > - : public binary_function < - 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 - { - return ( lhs < rhs ); - } -}; -} - -//////////////////////////////////////////////////////////////////////////////// - -#endif // end file guardian - diff --git a/shared/loki/Threads.h b/shared/loki/Threads.h deleted file mode 100644 index 690ca50f..00000000 --- a/shared/loki/Threads.h +++ /dev/null @@ -1,609 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_THREADS_INC_ -#define LOKI_THREADS_INC_ - -// $Id: Threads.h 902 2008-11-10 05:47:06Z rich_sposato $ - - -/// @defgroup ThreadingGroup Threading -/// Policies to for the threading model: -/// -/// - SingleThreaded -/// - ObjectLevelLockable -/// - ClassLevelLockable -/// -/// All classes in Loki have configurable threading model. -/// -/// The macro LOKI_DEFAULT_THREADING selects the default -/// threading model for certain components of Loki -/// (it affects only default template arguments) -/// -/// \par Usage: -/// -/// To use a specific threading model define -/// -/// - nothing, single-theading is default -/// - LOKI_OBJECT_LEVEL_THREADING for object-level-threading -/// - LOKI_CLASS_LEVEL_THREADING for class-level-threading -/// -/// \par Supported platfroms: -/// -/// - Windows (windows.h) -/// - POSIX (pthread.h): -/// No recursive mutex support with pthread. -/// This means: calling Lock() on a Loki::Mutex twice from the -/// same thread before unlocking the mutex deadlocks the system. -/// To avoid this redesign your synchronization. See also: -/// http://sourceforge.net/tracker/index.php?func=detail&aid=1516182&group_id=29557&atid=396647 - - -#include <cassert> - -#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 - -#else - -#define LOKI_DEFAULT_THREADING ::Loki::SingleThreaded -#define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::SingleThreaded - -#endif - -#ifndef LOKI_DEFAULT_MUTEX -#define LOKI_DEFAULT_MUTEX ::Loki::Mutex -#endif - -#ifdef LOKI_WINDOWS_H - -#define LOKI_THREADS_MUTEX(x) CRITICAL_SECTION (x); -#define LOKI_THREADS_MUTEX_INIT(x) ::InitializeCriticalSection (x) -#define LOKI_THREADS_MUTEX_DELETE(x) ::DeleteCriticalSection (x) -#define LOKI_THREADS_MUTEX_LOCK(x) ::EnterCriticalSection (x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) ::LeaveCriticalSection (x) -#define LOKI_THREADS_LONG LONG -#define LOKI_THREADS_MUTEX_CTOR(x) - -#define LOKI_THREADS_ATOMIC_FUNCTIONS \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval *= val; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval /= val; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - ++lval; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - --lval; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(volatile IntType& lval, const IntType val) \ - { InterlockedExchange(&const_cast<IntType&>(lval), val); } \ - \ - static void AtomicAssign(IntType& lval, volatile const IntType& val) \ - { InterlockedExchange(&lval, val); } \ - \ - static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - ++lval; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - --lval; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicAdd(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval += val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicSubtract(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval -= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval *= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval /= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } - -#elif defined(LOKI_PTHREAD_H) - - -#define LOKI_THREADS_MUTEX(x) pthread_mutex_t (x); - -#define LOKI_THREADS_MUTEX_INIT(x) ::pthread_mutex_init(x, 0) - -// define to 1 to enable recursive mutex support -#if 0 -// experimental recursive mutex support -#define LOKI_THREADS_MUTEX_CTOR(x) : x(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) -#else -// no recursive mutex support -#define LOKI_THREADS_MUTEX_CTOR(x) -#endif - -#define LOKI_THREADS_MUTEX_DELETE(x) ::pthread_mutex_destroy (x) -#define LOKI_THREADS_MUTEX_LOCK(x) ::pthread_mutex_lock (x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) ::pthread_mutex_unlock (x) -#define LOKI_THREADS_LONG long - -#define LOKI_THREADS_ATOMIC(x) \ - pthread_mutex_lock(&atomic_mutex_); \ - x; \ - pthread_mutex_unlock(&atomic_mutex_) - -#define LOKI_THREADS_ATOMIC_FUNCTIONS \ - private: \ - static pthread_mutex_t atomic_mutex_; \ - public: \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval *= val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval /= val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - ++lval; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - --lval; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval = val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(IntType& lval, volatile const IntType& val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval = val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - ++lval; \ - matches = ( compare == lval ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - --lval; \ - matches = ( compare == lval ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval *= val; \ - matches = ( lval == compare ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval /= val; \ - matches = ( lval == compare ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } - -#else // single threaded - -#define LOKI_THREADS_MUTEX(x) -#define LOKI_THREADS_MUTEX_INIT(x) -#define LOKI_THREADS_MUTEX_DELETE(x) -#define LOKI_THREADS_MUTEX_LOCK(x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) -#define LOKI_THREADS_LONG -#define LOKI_THREADS_MUTEX_CTOR(x) - -#endif - - - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class Mutex -// -/// \ingroup ThreadingGroup -/// A simple and portable Mutex. A default policy class for locking objects. -//////////////////////////////////////////////////////////////////////////////// - -class Mutex -{ -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_) -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \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 - { - Lock() {} - explicit Lock(const SingleThreaded&) {} - explicit Lock(const SingleThreaded*) {} - }; - - typedef Host VolatileType; - - typedef int IntType; - - 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 AtomicMultiply(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 AtomicDecrement(volatile IntType& lval) - { return --lval; } - - static void AtomicAssign(volatile IntType& lval, const 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 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 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 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_; - -public: - ObjectLevelLockable() : mtx_() {} - - ObjectLevelLockable(const ObjectLevelLockable&) : mtx_() {} - - ~ObjectLevelLockable() {} - - class Lock; - friend class Lock; - - /// \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(); - } - - /// 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_; - }; - - 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 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 -{ - struct Initializer - { - bool init_; - MutexPolicy mtx_; - - Initializer() : init_(false), mtx_() - { - init_ = true; - } - - ~Initializer() - { - assert(init_); - } - }; - - static Initializer initializer_; - -public: - - class Lock; - friend class Lock; - - /// \struct Lock - /// Lock class to lock on class level - class Lock - { - 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 - -}; - -#ifdef LOKI_PTHREAD_H -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_; - -#endif // #if defined(LOKI_WINDOWS_H) || defined(LOKI_PTHREAD_H) - -} // namespace Loki - - -#endif // end file guardian - diff --git a/shared/loki/Tuple.h b/shared/loki/Tuple.h deleted file mode 100644 index ec5ae213..00000000 --- a/shared/loki/Tuple.h +++ /dev/null @@ -1,22 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: June 20, 2001 - -//////////////////////////////////////////////////////////////////////////////// -// This file is intentionally left empty -// Due to compiler limitations, its contents has been moved to -// HierarchyGenerators.h -//////////////////////////////////////////////////////////////////////////////// diff --git a/shared/loki/TypeManip.h b/shared/loki/TypeManip.h deleted file mode 100644 index 7933e340..00000000 --- a/shared/loki/TypeManip.h +++ /dev/null @@ -1,290 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_TYPEMANIP_INC_ -#define LOKI_TYPEMANIP_INC_ - -// $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $ - - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template Int2Type -// Converts each integral constant into a unique type -// Invocation: Int2Type<v> where v is a compile-time constant integral -// Defines 'value', an enum that evaluates to v -//////////////////////////////////////////////////////////////////////////////// - -template <int v> -struct Int2Type -{ - enum { value = v }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Type2Type -// Converts each type into a unique, insipid type -// Invocation Type2Type<T> where T is a type -// Defines the type OriginalType which maps back to T -//////////////////////////////////////////////////////////////////////////////// - -template <typename T> -struct Type2Type -{ - typedef T OriginalType; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Select -// Selects one of two types based upon a boolean constant -// Invocation: Select<flag, T, U>::Result -// where: -// flag is a compile-time boolean constant -// T and U are types -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template IsSameType -// Return true iff two given types are the same -// Invocation: SameType<T, U>::value -// where: -// T and U are types -// 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 }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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(); -}; -} - -//////////////////////////////////////////////////////////////////////////////// -// class template Conversion -// Figures out the conversion relationships between two types -// Invocations (T and U are types): -// a) Conversion<T, U>::exists -// returns (at compile time) true if there is an implicit conversion from T -// to U (example: Derived to Base) -// b) Conversion<T, U>::exists2Way -// returns (at compile time) true if there are both conversions from T -// to U and from U to T (example: int to char and back) -// c) Conversion<T, U>::sameType -// returns (at compile time) true if T and U represent the same type -// -// 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; -#ifndef __MWERKS__ - enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) }; -#else - 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 }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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 -// same type. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -//////////////////////////////////////////////////////////////////////////////// - -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) - }; - - // Dummy enum to make sure that both classes are fully defined. - enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) }; -}; - -template <> -struct SuperSubclass<void, void> -{ - enum { value = false }; -}; - -template <class 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) - }; - - // Dummy enum to make sure that both classes are fully defined. - enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) }; -}; - -template <class T> -struct SuperSubclass<T, void> -{ - enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists && - !::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 ) }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template SuperSubclassStrict -// 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. -//////////////////////////////////////////////////////////////////////////////// - -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) - }; - - // Dummy enum to make sure that both classes are fully defined. - enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) }; -}; - -template<> -struct SuperSubclassStrict<void, void> -{ - enum { value = false }; -}; - -template<class 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) - }; - - // Dummy enum to make sure that both classes are fully defined. - enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) }; -}; - -template<class T> -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) - }; - - // Dummy enum to make sure that both classes are fully defined. - enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) }; -}; - - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// 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 -// same type. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -// Deprecated: Use SuperSubclass class template instead. -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_SUPERSUBCLASS(T, U) \ - ::Loki::SuperSubclass<T,U>::value - -//////////////////////////////////////////////////////////////////////////////// -// macro SUPERSUBCLASS_STRICT -// 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. -// Deprecated: Use SuperSubclassStrict class template instead. -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_SUPERSUBCLASS_STRICT(T, U) \ - ::Loki::SuperSubclassStrict<T,U>::value - - -#endif // end file guardian - diff --git a/shared/loki/TypeTraits.h b/shared/loki/TypeTraits.h deleted file mode 100644 index 28d0f0c1..00000000 --- a/shared/loki/TypeTraits.h +++ /dev/null @@ -1,2236 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_TYPETRAITS_INC_ -#define LOKI_TYPETRAITS_INC_ - -// $Id: TypeTraits.h 835 2007-08-02 19:39:02Z syntheticpp $ - - -#include "Typelist.h" -#include "Sequence.h" - -#if (defined _MSC_VER) && (_MSC_VER < 1400) -#include <string> -#endif - - -#ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored -#endif - -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 -// 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 -// integral type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - -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 -// 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 -// integral type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - -template <typename T> -struct IsCustomSignedInt -{ - enum { value = 0 }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template IsCustomFloat -// Offers a means to integrate nonstandard floating point types with the -// TypeTraits class template defined below. -// Invocation: IsCustomFloat<T> where T is any type -// Defines 'value', an enum that is 1 iff T is a custom built-in -// floating point type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - -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; -#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 - -//////////////////////////////////////////////////////////////////////////////// -// class template TypeTraits -// -// Figures out at compile time various properties of any given type -// 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 -// 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 -// 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 -// - isStdSignedInt : returns true if T is a standard signed integral type -// - isStdIntegral : returns true if T is a standard integral type -// - isStdFloat : returns true if T is a standard floating-point type -// - isStdArith : returns true if T is a standard arithmetic type -// - isStdFundamental: returns true if T is a standard fundamental type -// - isUnsignedInt : returns true if T is a unsigned integral type -// - isSignedInt : returns true if T is a signed integral type -// - isIntegral : returns true if T is a integral type -// - 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 -// 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 -// T, if any -// - ParameterType : returns the optimal type to be used as a parameter -// for functions that take 'const T's -// -//////////////////////////////////////////////////////////////////////////////// - -template <typename T> -class TypeTraits -{ -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; -}; -} - -#ifdef _MSC_VER -#pragma warning( pop ) -#endif // _MSC_VER - - -#endif // end file guardian - diff --git a/shared/loki/Typelist.h b/shared/loki/Typelist.h deleted file mode 100644 index e512ac83..00000000 --- a/shared/loki/Typelist.h +++ /dev/null @@ -1,459 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_TYPELIST_INC_ -#define LOKI_TYPELIST_INC_ - -// $Id: Typelist.h 749 2006-10-17 19:49:26Z syntheticpp $ - - -#include "NullType.h" -#include "TypeManip.h" -#include "TypelistMacros.h" - - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template Typelist -// The building block of typelists of any length -// Use it through the LOKI_TYPELIST_NN macros -// Defines nested types: -// Head (first element, a non-typelist type by convention) -// Tail (second element, can be another typelist) -//////////////////////////////////////////////////////////////////////////////// - -template <class T, class U> -struct Typelist -{ - typedef T Head; - typedef U Tail; -}; - -// Typelist utility algorithms - -namespace TL -{ - -//////////////////////////////////////////////////////////////////////////////// -// class template MakeTypelist -// Takes a number of arguments equal to its numeric suffix -// The arguments are type names. -// MakeTypelist<T1, T2, ...>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Length -// Computes the length of a typelist -// Invocation (TList is a typelist): -// Length<TList>::value -// returns a compile-time constant containing the length of TList, not counting -// 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 }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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 -// 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 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 -// constant): -// a) TypeAt<TList, index>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template IndexOf -// Finds the index of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// IndexOf<TList, T>::value -// 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) }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Append -// Appends a type or a typelist to another -// Invocation (TList is a typelist and T is either a type or a typelist): -// Append<TList, T>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Erase -// Erases the first occurence, if any, of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// Erase<TList, T>::Result -// 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 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template EraseAll -// Erases all first occurences, if any, of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// EraseAll<TList, T>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template NoDuplicates -// Removes all duplicate types in a typelist -// Invocation (TList is a typelist): -// NoDuplicates<TList, T>::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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Replace -// Replaces the first occurence of a type in a typelist, with another type -// Invocation (TList is a typelist, T, U are types): -// Replace<TList, T, U>::Result -// 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 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template ReplaceAll -// Replaces all occurences of a type in a typelist, with another type -// Invocation (TList is a typelist, T, U are types): -// Replace<TList, T, U>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Reverse -// Reverses a typelist -// Invocation (TList is a typelist): -// Reverse<TList>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template MostDerived -// Finds the type in a typelist that is the most derived from a given type -// Invocation (TList is a typelist, T is a type): -// MostDerived<TList, T>::Result -// 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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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 -} // namespace Loki - - -#endif // end file guardian - diff --git a/shared/loki/TypelistMacros.h b/shared/loki/TypelistMacros.h deleted file mode 100644 index 4bd34cb7..00000000 --- a/shared/loki/TypelistMacros.h +++ /dev/null @@ -1,353 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_TYPELISTMACROS_INC_ -#define LOKI_TYPELISTMACROS_INC_ - -// $Id: TypelistMacros.h 749 2006-10-17 19:49:26Z syntheticpp $ - - -//#define LOKI_DISABLE_TYPELIST_MACROS -#ifndef LOKI_DISABLE_TYPELIST_MACROS - -//////////////////////////////////////////////////////////////////////////////// -// 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 -// all types passed as arguments, in that order. -// Example: LOKI_TYPELIST_2(char, int) generates a type containing char and int. -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType> - -#define LOKI_TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) > - -#define LOKI_TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) > - -#define LOKI_TYPELIST_4(T1, T2, T3, T4) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_3(T2, T3, T4) > - -#define LOKI_TYPELIST_5(T1, T2, T3, T4, T5) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_4(T2, T3, T4, T5) > - -#define LOKI_TYPELIST_6(T1, T2, T3, T4, T5, T6) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_5(T2, T3, T4, T5, T6) > - -#define LOKI_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_6(T2, T3, T4, T5, T6, T7) > - -#define LOKI_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) > - -#define LOKI_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) > - -#define LOKI_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) > - -#define LOKI_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) > - -#define LOKI_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12) > - -#define LOKI_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ - ::Loki::Typelist<T1, LOKI_TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13) > - -#define LOKI_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14) \ -::Loki::Typelist<T1, LOKI_TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14) > - -#define LOKI_TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15) \ -::Loki::Typelist<T1, LOKI_TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15) > - -#define LOKI_TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16) \ -::Loki::Typelist<T1, LOKI_TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16) > - -#define LOKI_TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17) \ -::Loki::Typelist<T1, LOKI_TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17) > - -#define LOKI_TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18) \ -::Loki::Typelist<T1, LOKI_TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18) > - -#define LOKI_TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19) \ -::Loki::Typelist<T1, LOKI_TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19) > - -#define LOKI_TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \ -::Loki::Typelist<T1, LOKI_TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) > - -#define LOKI_TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \ -::Loki::Typelist<T1, LOKI_TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) > - -#define LOKI_TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \ -::Loki::Typelist<T1, LOKI_TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) > - -#define LOKI_TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \ -::Loki::Typelist<T1, LOKI_TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) > - -#define LOKI_TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \ -::Loki::Typelist<T1, LOKI_TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) > - -#define LOKI_TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \ -::Loki::Typelist<T1, LOKI_TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25) > - -#define LOKI_TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26) \ -::Loki::Typelist<T1, LOKI_TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26) > - -#define LOKI_TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27) \ -::Loki::Typelist<T1, LOKI_TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27) > - -#define LOKI_TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28) \ -::Loki::Typelist<T1, LOKI_TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28) > - -#define LOKI_TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29) \ -::Loki::Typelist<T1, LOKI_TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29) > - -#define LOKI_TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \ -::Loki::Typelist<T1, LOKI_TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) > - -#define LOKI_TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \ -::Loki::Typelist<T1, LOKI_TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) > - -#define LOKI_TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \ -::Loki::Typelist<T1, LOKI_TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) > - -#define LOKI_TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \ -::Loki::Typelist<T1, LOKI_TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) > - -#define LOKI_TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \ -::Loki::Typelist<T1, LOKI_TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) > - -#define LOKI_TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35) \ -::Loki::Typelist<T1, LOKI_TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35) > - -#define LOKI_TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36) \ -::Loki::Typelist<T1, LOKI_TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36) > - -#define LOKI_TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37) \ -::Loki::Typelist<T1, LOKI_TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37) > - -#define LOKI_TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38) \ -::Loki::Typelist<T1, LOKI_TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38) > - -#define LOKI_TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39) \ -::Loki::Typelist<T1, LOKI_TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39) > - -#define LOKI_TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \ -::Loki::Typelist<T1, LOKI_TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) > - -#define LOKI_TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \ -::Loki::Typelist<T1, LOKI_TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) > - -#define LOKI_TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \ -::Loki::Typelist<T1, LOKI_TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) > - -#define LOKI_TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \ -::Loki::Typelist<T1, LOKI_TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) > - -#define LOKI_TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \ -::Loki::Typelist<T1, LOKI_TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) > - -#define LOKI_TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45) \ -::Loki::Typelist<T1, LOKI_TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45) > - -#define LOKI_TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46) \ -::Loki::Typelist<T1, LOKI_TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46) > - -#define LOKI_TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47) \ -::Loki::Typelist<T1, LOKI_TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47) > - -#define LOKI_TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48) \ -::Loki::Typelist<T1, LOKI_TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48) > - -#define LOKI_TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49) \ -::Loki::Typelist<T1, LOKI_TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49) > - -#define LOKI_TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \ -::Loki::Typelist<T1, LOKI_TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) > - -#endif //LOKI_DISABLE_TYPELIST_MACROS - -#endif // end file guardian - diff --git a/shared/loki/Visitor.h b/shared/loki/Visitor.h deleted file mode 100644 index 85b8acd2..00000000 --- a/shared/loki/Visitor.h +++ /dev/null @@ -1,355 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_VISITOR_INC_ -#define LOKI_VISITOR_INC_ - -// $Id: Visitor.h 751 2006-10-17 19:50:37Z syntheticpp $ - - -/// \defgroup VisitorGroup Visitor - -#include "Typelist.h" -#include "HierarchyGenerators.h" - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class BaseVisitor -/// -/// \ingroup VisitorGroup -/// The base class of any Acyclic Visitor -//////////////////////////////////////////////////////////////////////////////// - -class BaseVisitor -{ -public: - virtual ~BaseVisitor() {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \class Visitor -/// -/// \ingroup VisitorGroup -/// The building block of Acyclic Visitor -/// -/// \par Usage -/// -/// Defining the visitable class: -/// -/// \code -/// class RasterBitmap : public BaseVisitable<> -/// { -/// public: -/// LOKI_DEFINE_VISITABLE() -/// }; -/// \endcode -/// -/// Way 1 to define a visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<RasterBitmap>, -/// public Visitor<Paragraph> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// Way 2 to define the visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// Way 3 to define the visitor: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<Seq<RasterBitmap, Paragraph>::Type> -/// { -/// public: -/// void Visit(RasterBitmap&); // visit a RasterBitmap -/// void Visit(Paragraph &); // visit a Paragraph -/// }; -/// \endcode -/// -/// \par Using const visit functions: -/// -/// Defining the visitable class (true for const): -/// -/// \code -/// class RasterBitmap : public BaseVisitable<void, DefaultCatchAll, true> -/// { -/// public: -/// LOKI_DEFINE_CONST_VISITABLE() -/// }; -/// \endcode -/// -/// Defining the visitor which only calls const member functions: -/// \code -/// class SomeVisitor : -/// public BaseVisitor // required -/// public Visitor<RasterBitmap, void, true>, -/// { -/// public: -/// void Visit(const RasterBitmap&); // visit a RasterBitmap by a const member function -/// }; -/// \endcode -/// -/// \par Example: -/// -/// test/Visitor/main.cpp -//////////////////////////////////////////////////////////////////////////////// - -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; -}; - -//////////////////////////////////////////////////////////////////////////////// -// 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 : -// public BaseVisitor // required -// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)> -// { -// public: -// void Visit(RasterBitmap&); // visit a RasterBitmap -// void Visit(Paragraph &); // visit a Paragraph -// }; -//////////////////////////////////////////////////////////////////////////////// - -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; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// class template BaseVisitorImpl -// Implements non-strict visitation (you can implement only part of the Visit -// functions) -//////////////////////////////////////////////////////////////////////////////// - -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(); } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template BaseVisitable -//////////////////////////////////////////////////////////////////////////////// - -template <typename R, typename Visited> -struct DefaultCatchAll -{ - static R OnUnknownVisitor(Visited&, BaseVisitor&) - { return R(); } -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template 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> -{ -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)) - { - return p->Visit(visited); - } - return CatchAll<R, T>::OnUnknownVisitor(visited, guest); - } -}; - -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) - { - // 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); - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_VISITABLE() -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable -/// (in addition to deriving it from BaseVisitable<R>) -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_VISITABLE() \ - virtual ReturnType Accept(::Loki::BaseVisitor& guest) \ - { return AcceptImpl(*this, guest); } - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_CONST_VISITABLE() -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable by const member -/// functions (in addition to deriving it from BaseVisitable<R>) -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_CONST_VISITABLE() \ - virtual ReturnType Accept(::Loki::BaseVisitor& guest) const \ - { return AcceptImpl(*this, guest); } - -//////////////////////////////////////////////////////////////////////////////// -/// \class CyclicVisitor -/// -/// \ingroup VisitorGroup -/// 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> -{ -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); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -/// \def LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) -/// \ingroup VisitorGroup -/// Put it in every class that you want to make visitable by a cyclic visitor -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) \ - virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \ - { return guest.GenericVisit(*this); } - -} // namespace Loki - - - -#endif // end file guardian - diff --git a/shared/loki/readme.txt b/shared/loki/readme.txt deleted file mode 100644 index a35cf387..00000000 --- a/shared/loki/readme.txt +++ /dev/null @@ -1,12 +0,0 @@ -// $Id: readme.txt 753 2006-10-17 19:54:22Z syntheticpp $ - -The Golden Code -KEEPEN DER DAMDDEN FUGGERMUTTENS OTTEN DIS CODDEN FIL - -A compliant C++ compiler will compile all of this code as is. -See the respective vendor directories for code that actually compiles & runs. - -Note: Right now, this code contains CodeWarrior & gcc modifications, -which may be removed at a future point in time -(by moving them to a vendor specific implementation). -MKH
\ No newline at end of file diff --git a/shared/loki/static_check.h b/shared/loki/static_check.h deleted file mode 100644 index b4c455c9..00000000 --- a/shared/loki/static_check.h +++ /dev/null @@ -1,45 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// 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 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" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_STATIC_CHECK_INC_ -#define LOKI_STATIC_CHECK_INC_ - -// $Id: static_check.h 752 2006-10-17 19:52:18Z syntheticpp $ - - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// Helper structure for the STATIC_CHECK macro -//////////////////////////////////////////////////////////////////////////////// - -template<int> struct CompileTimeError; -template<> struct CompileTimeError<true> {}; -} - -//////////////////////////////////////////////////////////////////////////////// -// macro STATIC_CHECK -// Invocation: STATIC_CHECK(expr, id) -// where: -// expr is a compile-time integral or pointer expression -// id is a C++ identifier that does not need to be defined -// If expr is zero, id will appear in a compile-time error message. -//////////////////////////////////////////////////////////////////////////////// - -#define LOKI_STATIC_CHECK(expr, msg) \ - { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } - - -#endif // end file guardian - diff --git a/shared/long_path_prefix.h b/shared/long_path_prefix.h deleted file mode 100644 index ca6961a9..00000000 --- a/shared/long_path_prefix.h +++ /dev/null @@ -1,104 +0,0 @@ -// ************************************************************************** -// * 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 LONGPATHPREFIX_H_INCLUDED -#define LONGPATHPREFIX_H_INCLUDED - -#include "zstring.h" - -#ifndef FFS_WIN -#error use in windows build only! -#endif - -namespace zen -{ -//handle filenames longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix (Reference: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath) -/* -1. path must be absolute -2. if path is smaller than MAX_PATH nothing is changed! -3. path may already contain \\?\-prefix -*/ -Zstring applyLongPathPrefix(const Zstring& path); //throw() -Zstring applyLongPathPrefixCreateDir(const Zstring& path); //throw() -> special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold - -Zstring removeLongPathPrefix(const Zstring& path); //throw() -} - - - - - - - - - - - - - - - - - - - - - - -//################## implementation ################## - -//there are two flavors of long path prefix: one for UNC paths, one for regular paths -const Zstring LONG_PATH_PREFIX = Zstr("\\\\?\\"); -const Zstring LONG_PATH_PREFIX_UNC = Zstr("\\\\?\\UNC"); - -template <size_t max_path> -inline -Zstring applyLongPathPrefixImpl(const Zstring& path) -{ - assert(!path.empty()); //nicely check almost all WinAPI accesses! - 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 - else - return LONG_PATH_PREFIX + path; //prepend \\?\ prefix - } - - return path; //fallback -} - - -inline -Zstring zen::applyLongPathPrefix(const Zstring& path) -{ - return applyLongPathPrefixImpl<MAX_PATH>(path); -} - - -inline -Zstring zen::applyLongPathPrefixCreateDir(const Zstring& path) //throw() -{ - //special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold - return applyLongPathPrefixImpl < MAX_PATH - 12 > (path); -} - - -inline -Zstring zen::removeLongPathPrefix(const Zstring& path) //throw() -{ - if (path.StartsWith(LONG_PATH_PREFIX)) - { - if (path.StartsWith(LONG_PATH_PREFIX_UNC)) //UNC-name - return Zstring(path).Replace(LONG_PATH_PREFIX_UNC, Zstr("\\"), false); - else - return Zstring(path).Replace(LONG_PATH_PREFIX, Zstr(""), false); - } - - return path; //fallback -} - -#endif //LONGPATHPREFIX_H_INCLUDED diff --git a/shared/mouse_move_dlg.cpp b/shared/mouse_move_dlg.cpp deleted file mode 100644 index 7981df49..00000000 --- a/shared/mouse_move_dlg.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************** -// * 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" -#include <wx/stattext.h> -#include <wx/statbmp.h> -#include <wx/statline.h> -#include <wx/animate.h> -#include <wx/panel.h> -#include <wx/gauge.h> -#include <wx/statusbr.h> - -using namespace zen; - -namespace -{ -void getAllChildren(wxWindow& parent, std::vector<wxWindow*>& out) -{ - wxWindowList& wl = parent.GetChildren(); - for (wxWindowList::iterator i = wl.begin(); i != wl.end(); ++i) - { - if (dynamic_cast<wxStaticText*> (*i) || //redirect clicks on these "dead" controls to move dialog instead - dynamic_cast<wxStaticBitmap*> (*i) || - dynamic_cast<wxAnimationCtrl*>(*i) || - dynamic_cast<wxGauge*> (*i) || - dynamic_cast<wxStaticLine*> (*i) || - dynamic_cast<wxStatusBar*> (*i) || - dynamic_cast<wxPanel*> (*i)) - out.push_back(*i); - getAllChildren(**i, out); - } -} -} - -MouseMoveWindow::MouseMoveWindow(wxWindow& parent, bool includeParent) : wxWindow(&parent, wxID_ANY) -{ - std::vector<wxWindow*> windList; - if (includeParent) - windList.push_back(&parent); - getAllChildren(parent, windList); - - 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(); -} - - -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 deleted file mode 100644 index 4412529c..00000000 --- a/shared/mouse_move_dlg.h +++ /dev/null @@ -1,31 +0,0 @@ -// ************************************************************************** -// * 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 zen -{ - -/* -move dialog by mouse-dragging contained sub-windows: just attach to parent via new in constructor: - new MouseMoveWindow(parent); //ownership passed to parent -*/ -class MouseMoveWindow : public wxWindow //private wxEvtHandler -{ -public: - MouseMoveWindow(wxWindow& parent, bool includeParent = true); //parent including all relevant child elements - - virtual bool allowMove(const wxMouseEvent& event) { return true; } - -private: - void LeftButtonDown(wxMouseEvent& event); -}; -} - -#endif // MOUSEMOVEWINDOW_H_INCLUDED diff --git a/shared/notify_removal.cpp b/shared/notify_removal.cpp deleted file mode 100644 index 3a9239db..00000000 --- a/shared/notify_removal.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// ************************************************************************** -// * 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 "notify_removal.h" -#include <set> -#include "last_error.h" -#include "Loki/ScopeGuard.h" -#include <algorithm> -#include <boost/bind.hpp> -#include <dbt.h> - -using namespace zen; - - -/* -//convert bitmask into "real" drive-letter -Zstring getDriveFromMask(ULONG unitmask) -{ - for (int i = 0; i < 26; ++i) - { - if (unitmask & 0x1) - return Zstring() + static_cast<DefaultChar>(DefaultChar('A') + i) + DefaultStr(":\\"); - unitmask >>= 1; - } - return Zstring(); -} -*/ - -namespace -{ -bool messageProviderConstructed = false; -} - - -class MessageProvider //administrates a single dummy window to receive messages -{ -public: - static MessageProvider& instance() //throw (FileError) - { - static MessageProvider inst; - messageProviderConstructed = true; - return inst; - } - - class Listener - { - public: - virtual ~Listener() {} - virtual void onMessage(UINT message, WPARAM wParam, LPARAM lParam) = 0; //throw()! - }; - void registerListener(Listener& l) { listener.insert(&l); } - void unregisterListener(Listener& l) { listener.erase(&l); } //don't unregister objects with static lifetime - - HWND getWnd() const { return windowHandle; } //get handle in order to register additional notifications - -private: - MessageProvider(); - ~MessageProvider(); - MessageProvider(const MessageProvider&); - MessageProvider& operator=(const MessageProvider&); - - static const wchar_t WINDOW_NAME[]; - - friend LRESULT CALLBACK topWndProc(HWND, UINT, WPARAM, LPARAM); - void processMessage(UINT message, WPARAM wParam, LPARAM lParam); - - const HINSTANCE process; - HWND windowHandle; - - std::set<Listener*> listener; -}; - - -const wchar_t MessageProvider::WINDOW_NAME[] = L"E6AD5EB1-527B-4EEF-AC75-27883B233380"; //random name - - -LRESULT CALLBACK topWndProc( - HWND hwnd, //handle to window - UINT uMsg, //message identifier - WPARAM wParam, //first message parameter - LPARAM lParam) //second message parameter -{ - if (messageProviderConstructed) //attention: this callback is triggered in the middle of singleton construction! It is a bad idea to to call back at this time! - try - { - MessageProvider::instance().processMessage(uMsg, wParam, lParam); //not supposed to throw - } - catch (...) {} - - return ::DefWindowProc(hwnd, uMsg, wParam, lParam); -} - - -MessageProvider::MessageProvider() : - process(::GetModuleHandle(NULL)), //get program's module handle - windowHandle(NULL) -{ - if (process == NULL) - throw zen::FileError(std::wstring(L"Could not start monitoring window notifications:") + "\n\n" + getLastErrorFormatted() + " (GetModuleHandle)"); - - //register the main window class - WNDCLASS wc = {}; - wc.lpfnWndProc = topWndProc; - wc.hInstance = process; - wc.lpszClassName = WINDOW_NAME; - - if (::RegisterClass(&wc) == 0) - throw zen::FileError(std::wstring(L"Could not start monitoring window notifications:") + "\n\n" + getLastErrorFormatted() + " (RegisterClass)"); - - Loki::ScopeGuard guardClass = Loki::MakeGuard(::UnregisterClass, WINDOW_NAME, process); - - //create dummy-window - windowHandle = ::CreateWindow( - WINDOW_NAME, //LPCTSTR lpClassName OR ATOM in low-order word! - NULL, //LPCTSTR lpWindowName, - 0, //DWORD dwStyle, - 0, //int x, - 0, //int y, - 0, //int nWidth, - 0, //int nHeight, - 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)! - NULL, //HMENU hMenu, - process, //HINSTANCE hInstance, - NULL); //LPVOID lpParam - if (windowHandle == NULL) - throw zen::FileError(std::wstring(L"Could not start monitoring window notifications:") + "\n\n" + getLastErrorFormatted() + " (CreateWindow)"); - - guardClass.Dismiss(); -} - - -MessageProvider::~MessageProvider() -{ - //clean-up in reverse order - ::DestroyWindow(windowHandle); - ::UnregisterClass(WINDOW_NAME, //LPCTSTR lpClassName OR ATOM in low-order word! - process); //HINSTANCE hInstance -} - - -void MessageProvider::processMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - std::for_each(listener.begin(), listener.end(), boost::bind(&Listener::onMessage, _1, message, wParam, lParam)); -} -//#################################################################################################### - - -class NotifyRequestDeviceRemoval::Pimpl : private MessageProvider::Listener -{ -public: - Pimpl(NotifyRequestDeviceRemoval& parent, HANDLE hDir) : //throw (FileError) - parent_(parent) - { - MessageProvider::instance().registerListener(*this); //throw (FileError) - - //register handles to receive notifications - DEV_BROADCAST_HANDLE filter = {}; - filter.dbch_size = sizeof(filter); - filter.dbch_devicetype = DBT_DEVTYP_HANDLE; - filter.dbch_handle = hDir; - - hNotification = ::RegisterDeviceNotification( - MessageProvider::instance().getWnd(), //__in HANDLE hRecipient, - &filter, //__in LPVOID NotificationFilter, - DEVICE_NOTIFY_WINDOW_HANDLE); //__in DWORD Flags - if (hNotification == NULL) - { - const DWORD lastError = ::GetLastError(); - if (lastError != ERROR_CALL_NOT_IMPLEMENTED && //fail on SAMBA share: this shouldn't be a showstopper! - lastError != ERROR_SERVICE_SPECIFIC_ERROR && //neither should be fail for "Pogoplug" mapped network drives - lastError != ERROR_INVALID_DATA) //this seems to happen for a NetDrive-mapped FTP server - throw zen::FileError(std::wstring(L"Could not register device removal notifications:") + "\n\n" + getLastErrorFormatted(lastError)); - } - } - - ~Pimpl() - { - ::UnregisterDeviceNotification(hNotification); - MessageProvider::instance().unregisterListener(*this); - } - -private: - Pimpl(Pimpl&); - Pimpl& operator=(Pimpl&); - - virtual void onMessage(UINT message, WPARAM wParam, LPARAM lParam) //throw()! - { - //DBT_DEVICEQUERYREMOVE example: http://msdn.microsoft.com/en-us/library/aa363427(v=VS.85).aspx - if (message == WM_DEVICECHANGE) - { - if ( wParam == DBT_DEVICEQUERYREMOVE || - wParam == DBT_DEVICEQUERYREMOVEFAILED || - wParam == DBT_DEVICEREMOVECOMPLETE) - { - PDEV_BROADCAST_HDR header = reinterpret_cast<PDEV_BROADCAST_HDR>(lParam); - if (header->dbch_devicetype == DBT_DEVTYP_HANDLE) - { - PDEV_BROADCAST_HANDLE body = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lParam); - -#ifdef __MINGW32__ - const HDEVNOTIFY requestNotification = reinterpret_cast<HDEVNOTIFY>(body->dbch_hdevnotify); -#else - const HDEVNOTIFY requestNotification = body->dbch_hdevnotify; -#endif - if (requestNotification == hNotification) //is it for the notification we registered? - switch (wParam) - { - case DBT_DEVICEQUERYREMOVE: - parent_.onRequestRemoval(body->dbch_handle); - break; - case DBT_DEVICEQUERYREMOVEFAILED: - parent_.onRemovalFinished(body->dbch_handle, false); - break; - case DBT_DEVICEREMOVECOMPLETE: - parent_.onRemovalFinished(body->dbch_handle, true); - break; - } - } - } - } - } - - NotifyRequestDeviceRemoval& parent_; - HDEVNOTIFY hNotification; -}; -//#################################################################################################### - - -NotifyRequestDeviceRemoval::NotifyRequestDeviceRemoval(HANDLE hDir) -{ - pimpl.reset(new Pimpl(*this, hDir)); -} - - -NotifyRequestDeviceRemoval::~NotifyRequestDeviceRemoval() {} //make sure ~auto_ptr() works with complete type diff --git a/shared/notify_removal.h b/shared/notify_removal.h deleted file mode 100644 index f9d1cbaf..00000000 --- a/shared/notify_removal.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************** -// * 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 NOTIFY_H_INCLUDED -#define NOTIFY_H_INCLUDED - -#ifndef FFS_WIN -#error use in windows build only -#endif - -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "file_error.h" -#include <vector> -#include <memory> - -//handle (user-) request for device removal via template method pattern -//evaluate directly after processing window messages -class NotifyRequestDeviceRemoval -{ -public: - NotifyRequestDeviceRemoval(HANDLE hDir); //throw FileError - virtual ~NotifyRequestDeviceRemoval(); - -private: - virtual void onRequestRemoval(HANDLE hnd) = 0; //throw()! - //NOTE: onRemovalFinished is NOT guaranteed to execute after onRequestRemoval()! but most likely will - virtual void onRemovalFinished(HANDLE hnd, bool successful) = 0; //throw()! - - NotifyRequestDeviceRemoval(NotifyRequestDeviceRemoval&); //no copying - void operator=(NotifyRequestDeviceRemoval&); // - - class Pimpl; - std::unique_ptr<Pimpl> pimpl; -}; - - -#endif // NOTIFY_H_INCLUDED diff --git a/shared/parse_lng.h b/shared/parse_lng.h deleted file mode 100644 index 034deb68..00000000 --- a/shared/parse_lng.h +++ /dev/null @@ -1,618 +0,0 @@ -// ************************************************************************** -// * 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 PARSE_LNG_HEADER_INCLUDED -#define PARSE_LNG_HEADER_INCLUDED - -#include <string> -#include <sstream> -#include <map> -#include <set> -#include <vector> -#include <algorithm> -#include <functional> -#include <cctype> -#include <list> -#include <stdexcept> - - -namespace lngfile -{ -//singular forms -typedef std::map <std::string, std::string> -TranslationMap; //orig |-> translation - -//plural forms -typedef std::pair<std::string, std::string> -SingularPluralPair; //1 house| n houses - -typedef std::vector<std::string> -PluralForms; //1 dom | 2 domy | 5 domów - -typedef std::map <SingularPluralPair, PluralForms> -TranslationPluralMap; //(sing/plu) |-> pluralforms - -struct TransHeader -{ - std::string languageName; //display name: "English (UK)" - std::string translatorName; //"ZenJu" - std::string localeName; //ISO 639 language code + ISO 3166 country code, e.g. "en_GB", or "en_US" - std::string flagFile; //"england.png" - int pluralCount; - std::string pluralDefinition; //"nplurals=2; plural= n == 1 ? 0 : 1" -}; - - -struct ParsingError -{ - ParsingError(size_t rowNo, size_t colNo) : row(rowNo), col(colNo) {} - size_t row; - size_t col; -}; -void parseLng(const std::string& fileStream, TransHeader& header, TranslationMap& out, TranslationPluralMap& pluralOut); //throw ParsingError -void parseHeader(const std::string& fileStream, TransHeader& header); //throw ParsingError - -class TranslationList; //unordered list of unique translation items -void generateLng(const TranslationList& in, const TransHeader& header, std::string& fileStream); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//--------------------------- implementation --------------------------- -class TranslationList //unordered list of unique translation items -{ -public: - void addItem(const std::string& orig, const std::string& trans) - { - if (!transUnique.insert(orig).second) return; - - dump.push_back(RegularItem(std::make_pair(orig, trans))); - sequence.push_back(&dump.back()); - } - void addPluralItem(const SingularPluralPair& orig, const PluralForms& trans) - { - if (!pluralUnique.insert(orig).second) return; - - dumpPlural.push_back(PluralItem(std::make_pair(orig, trans))); - sequence.push_back(&dumpPlural.back()); - } - - bool untranslatedTextExists() const - { - for (std::list<RegularItem>::const_iterator i = dump.begin(); i != dump.end(); ++i) - if (i->value.second.empty()) - return true; - for (std::list<PluralItem>::const_iterator i = dumpPlural.begin(); i != dumpPlural.end(); ++i) - if (i->value.second.empty()) - return true; - return false; - } - -private: - friend void generateLng(const TranslationList& in, const TransHeader& header, std::string& fileStream); - - struct Item {virtual ~Item() {} }; - struct RegularItem : public Item { RegularItem(const TranslationMap ::value_type& val) : value(val) {} TranslationMap ::value_type value; }; - struct PluralItem : public Item { PluralItem (const TranslationPluralMap::value_type& val) : value(val) {} TranslationPluralMap::value_type value; }; - - std::vector<Item*> sequence; //dynamic list of translation elements - std::list<RegularItem> dump; //manage memory - std::list<PluralItem> dumpPlural; //manage memory - - std::set<TranslationMap ::key_type> transUnique; //check uniqueness - std::set<TranslationPluralMap::key_type> pluralUnique; // -}; - - -struct Token -{ - enum Type - { - //header information - TK_HEADER_BEGIN, - TK_HEADER_END, - TK_LANG_NAME_BEGIN, - TK_LANG_NAME_END, - TK_TRANS_NAME_BEGIN, - TK_TRANS_NAME_END, - TK_LOCALE_NAME_BEGIN, - TK_LOCALE_NAME_END, - TK_FLAG_FILE_BEGIN, - TK_FLAG_FILE_END, - TK_PLURAL_COUNT_BEGIN, - TK_PLURAL_COUNT_END, - TK_PLURAL_DEF_BEGIN, - TK_PLURAL_DEF_END, - - //item level - TK_SRC_BEGIN, - TK_SRC_END, - TK_TRG_BEGIN, - TK_TRG_END, - TK_TEXT, - TK_PLURAL_BEGIN, - TK_PLURAL_END, - TK_END - }; - - Token(Type t) : type(t) {} - Type type; - - std::string text; -}; - - -class KnownTokens -{ -public: - typedef std::map<Token::Type, std::string> TokenMap; - - static const TokenMap& asList() - { - static KnownTokens inst; - return inst.tokens; - } - - static std::string text(Token::Type t) - { - TokenMap::const_iterator iter = asList().find(t); - return iter != asList().end() ? iter->second : std::string(); - } - -private: - KnownTokens() - { - //header information - tokens.insert(std::make_pair(Token::TK_HEADER_BEGIN, "<header>")); - tokens.insert(std::make_pair(Token::TK_HEADER_END, "</header>")); - tokens.insert(std::make_pair(Token::TK_LANG_NAME_BEGIN, "<language name>")); - tokens.insert(std::make_pair(Token::TK_LANG_NAME_END, "</language name>")); - tokens.insert(std::make_pair(Token::TK_TRANS_NAME_BEGIN, "<translator>")); - tokens.insert(std::make_pair(Token::TK_TRANS_NAME_END, "</translator>")); - tokens.insert(std::make_pair(Token::TK_LOCALE_NAME_BEGIN, "<locale>")); - tokens.insert(std::make_pair(Token::TK_LOCALE_NAME_END, "</locale>")); - tokens.insert(std::make_pair(Token::TK_FLAG_FILE_BEGIN, "<flag file>")); - tokens.insert(std::make_pair(Token::TK_FLAG_FILE_END, "</flag file>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_COUNT_BEGIN, "<plural forms>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_COUNT_END, "</plural forms>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_DEF_BEGIN, "<plural definition>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_DEF_END, "</plural definition>")); - - //item level - tokens.insert(std::make_pair(Token::TK_SRC_BEGIN, "<source>")); - tokens.insert(std::make_pair(Token::TK_SRC_END, "</source>")); - tokens.insert(std::make_pair(Token::TK_TRG_BEGIN, "<target>")); - tokens.insert(std::make_pair(Token::TK_TRG_END, "</target>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_BEGIN, "<pluralform>")); - tokens.insert(std::make_pair(Token::TK_PLURAL_END, "</pluralform>")); - } - TokenMap tokens; -}; - -struct IsWhiteSpace : public std::unary_function<char, bool> -{ - bool operator()(char c) const - { - const unsigned char usc = c; //caveat 1: std::isspace() takes an int, but expects an unsigned char - return usc < 128 && //caveat 2: some parts of UTF-8 chars are erroneously seen as whitespace, e.g. the a0 from "\xec\x8b\a0" (MSVC) - std::isspace(usc) != 0; //[!] - } -}; - -class Scanner -{ -public: - Scanner(const std::string& fileStream) : stream(fileStream), pos(stream.begin()) {} - - Token nextToken() - { - //skip whitespace - pos = std::find_if(pos, stream.end(), std::not1(IsWhiteSpace())); - - if (pos == stream.end()) - return Token(Token::TK_END); - - for (KnownTokens::TokenMap::const_iterator i = KnownTokens::asList().begin(); i != KnownTokens::asList().end(); ++i) - if (startsWith(i->second)) - { - pos += i->second.size(); - return Token(i->first); - } - - //rest must be "text" - std::string::const_iterator textBegin = pos; - while (pos != stream.end() && !startsWithKnownTag()) - pos = std::find(pos + 1, stream.end(), '<'); - - std::string text(textBegin, pos); - - normalize(text); //remove whitespace from end ect. - - if (text.empty() && pos == stream.end()) - return Token(Token::TK_END); - - Token out(Token::TK_TEXT); - out.text = text; - return out; - } - - std::pair<size_t, size_t> position() const //current (row/col) beginning with 1 - { - //seek last line break - std::string::const_iterator iter = pos; - while (iter != stream.begin() && *iter != '\n') - --iter; - - return std::make_pair(std::count(stream.begin(), pos, '\n') + 1, pos - iter); - } - -private: - bool startsWithKnownTag() const - { - for (KnownTokens::TokenMap::const_iterator i = KnownTokens::asList().begin(); i != KnownTokens::asList().end(); ++i) - if (startsWith(i->second)) - return true; - return false; - } - - bool startsWith(const std::string& prefix) const - { - if (stream.end() - pos < static_cast<int>(prefix.size())) - return false; - return std::equal(prefix.begin(), prefix.end(), pos); - } - - static void normalize(std::string& text) - { - //remmove whitespace from end - while (!text.empty() && IsWhiteSpace()(*text.rbegin())) - text.resize(text.size() - 1); - - //ensure c-style line breaks - - //Delimiter: - //---------- - //Linux: 0xA \n - //Mac: 0xD \r - //Win: 0xD 0xA \r\n <- language files are in Windows format - if (text.find('\r') != std::string::npos) - { - std::string tmp; - for (std::string::const_iterator i = text.begin(); i != text.end(); ++i) - if (*i == '\r') - { - std::string::const_iterator next = i + 1; - if (next != text.end() && *next == '\n') - ++i; - tmp += '\n'; - } - else - tmp += *i; - text = tmp; - } - } - - const std::string stream; - std::string::const_iterator pos; -}; - -template <class C, class T> -inline -std::basic_string<C> numberToString(const T& number) //convert number to string the C++ way -{ - std::basic_ostringstream<C> ss; - ss << number; - return ss.str(); -} - -template <class T, class C> -inline -T stringToNumber(const std::basic_string<C>& str) //convert string to number the C++ way -{ - T number = 0; - std::basic_istringstream<C>(str) >> number; - return number; -} - - -class LngParser -{ -public: - LngParser(const std::string& fileStream) : scn(fileStream), tk(scn.nextToken()) {} - - void parse(TranslationMap& out, TranslationPluralMap& pluralOut, TransHeader& header) - { - //header - parseHeader(header); - - //items - while (token().type != Token::TK_END) - parseRegular(out, pluralOut, header.pluralCount); - } - - void parseHeader(TransHeader& header) - { - consumeToken(Token::TK_HEADER_BEGIN); - - consumeToken(Token::TK_LANG_NAME_BEGIN); - header.languageName = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_LANG_NAME_END); - - consumeToken(Token::TK_TRANS_NAME_BEGIN); - header.translatorName = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_TRANS_NAME_END); - - consumeToken(Token::TK_LOCALE_NAME_BEGIN); - header.localeName = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_LOCALE_NAME_END); - - consumeToken(Token::TK_FLAG_FILE_BEGIN); - header.flagFile = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_FLAG_FILE_END); - - consumeToken(Token::TK_PLURAL_COUNT_BEGIN); - header.pluralCount = stringToNumber<int>(tk.text); - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_PLURAL_COUNT_END); - - consumeToken(Token::TK_PLURAL_DEF_BEGIN); - header.pluralDefinition = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_PLURAL_DEF_END); - - consumeToken(Token::TK_HEADER_END); - } - -private: - void parseRegular(TranslationMap& out, TranslationPluralMap& pluralOut, int formCount) - { - consumeToken(Token::TK_SRC_BEGIN); - - if (token().type == Token::TK_PLURAL_BEGIN) - return parsePlural(pluralOut, formCount); - - std::string original = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_SRC_END); - - consumeToken(Token::TK_TRG_BEGIN); - std::string translation; - if (token().type == Token::TK_TEXT) - { - translation = token().text; - nextToken(); - } - consumeToken(Token::TK_TRG_END); - - if (!translation.empty()) //only add if translation is existing - out.insert(std::make_pair(original, translation)); - } - - void parsePlural(TranslationPluralMap& pluralOut, int formCount) - { - //Token::TK_SRC_BEGIN already consumed - - consumeToken(Token::TK_PLURAL_BEGIN); - std::string engSingular = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_PLURAL_END); - - consumeToken(Token::TK_PLURAL_BEGIN); - std::string engPlural = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_PLURAL_END); - - consumeToken(Token::TK_SRC_END); - - consumeToken(Token::TK_TRG_BEGIN); - - PluralForms pluralList; - while (token().type == Token::TK_PLURAL_BEGIN) - { - consumeToken(Token::TK_PLURAL_BEGIN); - std::string pluralForm = tk.text; - consumeToken(Token::TK_TEXT); - consumeToken(Token::TK_PLURAL_END); - pluralList.push_back(pluralForm); - - } - - if (!pluralList.empty() && static_cast<int>(pluralList.size()) != formCount) //invalid number of plural forms - throw ParsingError(scn.position().first, scn.position().second); - - consumeToken(Token::TK_TRG_END); - - if (!pluralList.empty()) //only add if translation is existing - pluralOut.insert(std::make_pair(SingularPluralPair(engSingular, engPlural), pluralList)); - } - - - void nextToken() { tk = scn.nextToken(); } - const Token& token() const { return tk; } - - void consumeToken(Token::Type t) - { - if (token().type != t) - throw ParsingError(scn.position().first, scn.position().second); - nextToken(); - } - - Scanner scn; - Token tk; -}; - - -inline -void parseLng(const std::string& fileStream, TransHeader& header, TranslationMap& out, TranslationPluralMap& pluralOut) //throw ParsingError -{ - out.clear(); - pluralOut.clear(); - - //skip UTF-8 Byte Ordering Mark - const bool hasBOM = fileStream.size() >= 3 && fileStream.substr(0, 3) == "\xef\xbb\xbf"; - - LngParser prs(hasBOM ? fileStream.substr(3) : fileStream); - prs.parse(out, pluralOut, header); -} - - -inline -void parseHeader(const std::string& fileStream, TransHeader& header) //throw ParsingError -{ - //skip UTF-8 Byte Ordering Mark - const bool hasBOM = fileStream.size() >= 3 && fileStream.substr(0, 3) == "\xef\xbb\xbf"; - - LngParser prs(hasBOM ? fileStream.substr(3) : fileStream); - prs.parseHeader(header); -} - - -inline -void formatMultiLineText(std::string& text) -{ - if (text.find('\n') != std::string::npos) //multiple lines - { - if (*text.begin() != '\n') - text = '\n' + text; - if (*text.rbegin() != '\n') - text += '\n'; - } -} - - -const std::string LB = "\n"; -const std::string TAB = "\t"; - - -void generateLng(const TranslationList& in, const TransHeader& header, std::string& fileStream) -{ - //header - fileStream += KnownTokens::text(Token::TK_HEADER_BEGIN) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_LANG_NAME_BEGIN); - fileStream += header.languageName; - fileStream += KnownTokens::text(Token::TK_LANG_NAME_END) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_TRANS_NAME_BEGIN); - fileStream += header.translatorName; - fileStream += KnownTokens::text(Token::TK_TRANS_NAME_END) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_LOCALE_NAME_BEGIN); - fileStream += header.localeName; - fileStream += KnownTokens::text(Token::TK_LOCALE_NAME_END) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_FLAG_FILE_BEGIN); - fileStream += header.flagFile; - fileStream += KnownTokens::text(Token::TK_FLAG_FILE_END) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_COUNT_BEGIN); - fileStream += numberToString<char>(header.pluralCount); - fileStream += KnownTokens::text(Token::TK_PLURAL_COUNT_END) + LB; - - fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_DEF_BEGIN); - fileStream += header.pluralDefinition; - fileStream += KnownTokens::text(Token::TK_PLURAL_DEF_END) + LB; - - fileStream += KnownTokens::text(Token::TK_HEADER_END) + LB; - - fileStream += LB; - - - //items - for (std::vector<TranslationList::Item*>::const_iterator i = in.sequence.begin(); i != in.sequence.end(); ++i) - { - const TranslationList::RegularItem* regular = dynamic_cast<const TranslationList::RegularItem*>(*i); - const TranslationList::PluralItem* plural = dynamic_cast<const TranslationList::PluralItem*>(*i); - - if (regular) - { - std::string original = regular->value.first; - std::string translation = regular->value.second; - - formatMultiLineText(original); - formatMultiLineText(translation); - - fileStream += KnownTokens::text(Token::TK_SRC_BEGIN); - fileStream += original; - fileStream += KnownTokens::text(Token::TK_SRC_END) + LB; - - fileStream += KnownTokens::text(Token::TK_TRG_BEGIN); - fileStream += translation; - fileStream += KnownTokens::text(Token::TK_TRG_END) + LB + LB; - - } - else if (plural) - { - std::string engSingular = plural->value.first.first; - std::string engPlural = plural->value.first.second; - const PluralForms& forms = plural->value.second; - - formatMultiLineText(engSingular); - formatMultiLineText(engPlural); - - fileStream += KnownTokens::text(Token::TK_SRC_BEGIN) + LB; - fileStream += KnownTokens::text(Token::TK_PLURAL_BEGIN); - fileStream += engSingular; - fileStream += KnownTokens::text(Token::TK_PLURAL_END) + LB; - fileStream += KnownTokens::text(Token::TK_PLURAL_BEGIN); - fileStream += engPlural; - fileStream += KnownTokens::text(Token::TK_PLURAL_END) + LB; - fileStream += KnownTokens::text(Token::TK_SRC_END) + LB; - - fileStream += KnownTokens::text(Token::TK_TRG_BEGIN); - if (!forms.empty()) fileStream += LB; - - for (PluralForms::const_iterator j = forms.begin(); j != forms.end(); ++j) - { - std::string plForm = *j; - formatMultiLineText(plForm); - - fileStream += KnownTokens::text(Token::TK_PLURAL_BEGIN); - fileStream += plForm; - fileStream += KnownTokens::text(Token::TK_PLURAL_END) + LB; - } - fileStream += KnownTokens::text(Token::TK_TRG_END) + LB + LB; - } - else - { - throw std::logic_error("that's what you get for brittle design ;)"); - } - } -} -} - -#endif //PARSE_LNG_HEADER_INCLUDED diff --git a/shared/parse_plural.h b/shared/parse_plural.h deleted file mode 100644 index 1d2bcd95..00000000 --- a/shared/parse_plural.h +++ /dev/null @@ -1,412 +0,0 @@ -// ************************************************************************** -// * 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 PARSE_PLURAL_H_INCLUDED -#define PARSE_PLURAL_H_INCLUDED - -#include <list> -#include <memory> -#include "zbase.h" - - -//http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html -//http://translate.sourceforge.net/wiki/l10n/pluralforms -/* -Grammar for Plural forms parser -------------------------------- -expression: - conditional-expression - -conditional-expression: - logical-or-expression - logical-or-expression ? expression : expression - -logical-or-expression: - logical-and-expression - logical-or-expression || logical-and-expression - -logical-and-expression: - equality-expression - logical-and-expression && equality-expression - -equality-expression: - relational-expression - relational-expression == relational-expression - relational-expression != relational-expression - -relational-expression: - multiplicative-expression - multiplicative-expression > multiplicative-expression - multiplicative-expression < multiplicative-expression - multiplicative-expression >= multiplicative-expression - multiplicative-expression <= multiplicative-expression - -multiplicative-expression: - pm-expression - multiplicative-expression % pm-expression - -pm-expression: - N - Number - ( Expression ) -*/ - - - -//expression interface -struct Expression { virtual ~Expression() {} }; - -template <class T> -struct Expr : public Expression -{ - typedef T ValueType; - virtual ValueType eval() const = 0; -}; - -//specific binary expression based on STL function objects -template <class StlOp> -struct BinaryExp : public Expr<typename StlOp::result_type> -{ - typedef const Expr<typename StlOp::first_argument_type> SourceExp; - - BinaryExp(const SourceExp& lhs, const SourceExp& rhs, StlOp biop) : lhs_(lhs), rhs_(rhs), biop_(biop) {} - virtual typename StlOp::result_type eval() const { return biop_(lhs_.eval(), rhs_.eval()); } - const SourceExp& lhs_; - const SourceExp& rhs_; - StlOp biop_; -}; - -template <class StlOp> -inline -BinaryExp<StlOp> makeBiExp(const Expression& lhs, const Expression& rhs, StlOp biop) //throw (std::bad_cast) -{ - return BinaryExp<StlOp>(dynamic_cast<const Expr<typename StlOp::first_argument_type >&>(lhs), - dynamic_cast<const Expr<typename StlOp::second_argument_type>&>(rhs), biop); -} - -template <class Out> -struct TernaryExp : public Out -{ - TernaryExp(const Expr<bool>& ifExp, const Out& thenExp, const Out& elseExp) : ifExp_(ifExp), thenExp_(thenExp), elseExp_(elseExp) {} - virtual typename Out::ValueType eval() const { return ifExp_.eval() ? thenExp_.eval() : elseExp_.eval(); } - const Expr<bool>& ifExp_; - const Out& thenExp_; - const Out& elseExp_; -}; - -struct LiteralNumberEx : public Expr<int> -{ - LiteralNumberEx(int n) : n_(n) {} - virtual int eval() const { return n_; } - int n_; -}; - -struct NumberN : public Expr<int> -{ - NumberN(int& n) : n_(n) {} - virtual int eval() const { return n_; } - int& n_; -}; - - -typedef Zbase<char> Wstring; - - -class PluralForm -{ -public: - struct ParsingError {}; - - //.po format,e.g.: (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2) - PluralForm(const Wstring& phrase) : n_(0) - { - Parser(phrase, //in - expr, n_, dump); //out - } - - int getForm(int n) const { n_ = n ; return expr->eval(); } - -private: - typedef std::list<std::shared_ptr<Expression> > DumpList; - - struct Token - { - enum Type - { - TK_TERNARY_QUEST, - TK_TERNARY_COLON, - TK_OR, - TK_AND, - TK_EQUAL, - TK_NOT_EQUAL, - TK_LESS, - TK_LESS_EQUAL, - TK_GREATER, - TK_GREATER_EQUAL, - TK_MODULUS, - TK_N, - TK_NUMBER, - TK_BRACKET_LEFT, - TK_BRACKET_RIGHT, - TK_END - }; - - Token(Type t) : type(t), number(0) {} - - Type type; - int number; //if type == TK_NUMBER - }; - - class Scanner - { - public: - Scanner(const Wstring& phrase) : stream(phrase), pos(stream.begin()) - { - tokens.push_back(std::make_pair("?" , Token::TK_TERNARY_QUEST)); - tokens.push_back(std::make_pair(":" , Token::TK_TERNARY_COLON)); - tokens.push_back(std::make_pair("||", Token::TK_OR )); - tokens.push_back(std::make_pair("&&", Token::TK_AND )); - tokens.push_back(std::make_pair("==", Token::TK_EQUAL )); - tokens.push_back(std::make_pair("!=", Token::TK_NOT_EQUAL )); - tokens.push_back(std::make_pair("<=", Token::TK_LESS_EQUAL )); - tokens.push_back(std::make_pair("<" , Token::TK_LESS )); - tokens.push_back(std::make_pair(">=", Token::TK_GREATER_EQUAL)); - tokens.push_back(std::make_pair(">" , Token::TK_GREATER )); - tokens.push_back(std::make_pair("%" , Token::TK_MODULUS )); - tokens.push_back(std::make_pair("n" , Token::TK_N )); - tokens.push_back(std::make_pair("N" , Token::TK_N )); - tokens.push_back(std::make_pair("(" , Token::TK_BRACKET_LEFT )); - tokens.push_back(std::make_pair(")" , Token::TK_BRACKET_RIGHT)); - } - - Token nextToken() - { - //skip whitespace - pos = std::find_if(pos, stream.end(), std::not1(std::ptr_fun(std::iswspace))); - - if (pos == stream.end()) return Token(Token::TK_END); - - for (TokenList::const_iterator i = tokens.begin(); i != tokens.end(); ++i) - if (startsWith(i->first)) - { - pos += i->first.size(); - return Token(i->second); - } - - Wstring::const_iterator digitEnd = std::find_if(pos, stream.end(), std::not1(std::ptr_fun(std::iswdigit))); - int digitCount = digitEnd - pos; - if (digitCount != 0) - { - Token out(Token::TK_NUMBER); - out.number = Wstring(&*pos, digitCount).toNumber<int>(); - pos += digitCount; - return out; - } - - throw ParsingError(); //unknown token - } - - private: - bool startsWith(const Wstring& prefix) const - { - if (stream.end() - pos < static_cast<int>(prefix.size())) - return false; - return std::equal(prefix.begin(), prefix.end(), pos); - } - - typedef std::vector<std::pair<Wstring, Token::Type> > TokenList; - TokenList tokens; - - const Wstring stream; - Wstring::const_iterator pos; - }; - - - class Parser - { - public: - Parser(const Wstring& phrase, //in - const Expr<int>*& expr, int& n, PluralForm::DumpList& dump) ://out - scn(phrase), - tk(scn.nextToken()), - n_(n), - dump_(dump) - { - try - { - const Expression& e = parse(); - expr = &dynamic_cast<const Expr<int>&>(e); - } - catch (std::bad_cast&) { throw ParsingError(); } - - consumeToken(Token::TK_END); - } - - private: - void nextToken() { tk = scn.nextToken(); } - const Token& token() const { return tk; } - - void consumeToken(Token::Type t) - { - if (token().type != t) - throw ParsingError(); - nextToken(); - } - - const Expression& parse() { return parseConditional(); }; - - const Expression& parseConditional() - { - const Expression& e = parseLogicalOr(); - - if (token().type == Token::TK_TERNARY_QUEST) - { - nextToken(); - const Expression& thenEx = parse(); //associativity: <- - consumeToken(Token::TK_TERNARY_COLON); - const Expression& elseEx = parse(); // - - return manageObj(TernaryExp<Expr<int> >(dynamic_cast<const Expr<bool>&>(e), - dynamic_cast<const Expr<int>&>(thenEx), - dynamic_cast<const Expr<int>&>(elseEx))); - } - return e; - } - - const Expression& parseLogicalOr() - { - const Expression* e = &parseLogicalAnd(); - for (;;) //associativity: -> - if (token().type == Token::TK_OR) - { - nextToken(); - const Expression& rhs = parseLogicalAnd(); - e = &manageObj(makeBiExp(*e, rhs, std::logical_or<bool>())); - } - else break; - return *e; - } - - const Expression& parseLogicalAnd() - { - const Expression* e = &parseEquality(); - for (;;) //associativity: -> - if (token().type == Token::TK_AND) - { - nextToken(); - const Expression& rhs = parseEquality(); - - e = &manageObj(makeBiExp(*e, rhs, std::logical_and<bool>())); - } - else break; - return *e; - } - - const Expression& parseEquality() - { - const Expression& e = parseRelational(); - - Token::Type t = token().type; - if (t == Token::TK_EQUAL || t == Token::TK_NOT_EQUAL) //associativity: n/a - { - nextToken(); - const Expression& rhs = parseRelational(); - - if (t == Token::TK_EQUAL) return manageObj(makeBiExp(e, rhs, std::equal_to <int>())); - if (t == Token::TK_NOT_EQUAL) return manageObj(makeBiExp(e, rhs, std::not_equal_to<int>())); - } - return e; - } - - const Expression& parseRelational() - { - const Expression& e = parseMultiplicative(); - - Token::Type t = token().type; - if (t == Token::TK_LESS || //associativity: n/a - t == Token::TK_LESS_EQUAL || - t == Token::TK_GREATER || - t == Token::TK_GREATER_EQUAL) - { - nextToken(); - const Expression& rhs = parseMultiplicative(); - - if (t == Token::TK_LESS) return manageObj(makeBiExp(e, rhs, std::less <int>())); - if (t == Token::TK_LESS_EQUAL) return manageObj(makeBiExp(e, rhs, std::less_equal <int>())); - if (t == Token::TK_GREATER) return manageObj(makeBiExp(e, rhs, std::greater <int>())); - if (t == Token::TK_GREATER_EQUAL) return manageObj(makeBiExp(e, rhs, std::greater_equal<int>())); - } - return e; - } - - const Expression& parseMultiplicative() - { - const Expression* e = &parsePrimary(); - - for (;;) //associativity: -> - if (token().type == Token::TK_MODULUS) - { - nextToken(); - const Expression& rhs = parsePrimary(); - - //"compile-time" check: n % 0 - const LiteralNumberEx* literal = dynamic_cast<const LiteralNumberEx*>(&rhs); - if (literal && literal->eval() == 0) - throw ParsingError(); - - e = &manageObj(makeBiExp(*e, rhs, std::modulus<int>())); - } - else break; - return *e; - } - - const Expression& parsePrimary() - { - if (token().type == Token::TK_N) - { - nextToken(); - return manageObj(NumberN(n_)); - } - else if (token().type == Token::TK_NUMBER) - { - const int number = token().number; - nextToken(); - return manageObj(LiteralNumberEx(number)); - } - else if (token().type == Token::TK_BRACKET_LEFT) - { - nextToken(); - const Expression& e = parse(); - - consumeToken(Token::TK_BRACKET_RIGHT); - return e; - } - else - throw ParsingError(); - } - - template <class T> - const T& manageObj(const T& obj) - { - std::shared_ptr<Expression> newEntry(new T(obj)); - dump_.push_back(newEntry); - return static_cast<T&>(*dump_.back()); - } - - Scanner scn; - Token tk; - - int& n_; - DumpList& dump_; //manage polymorphc object lifetimes - }; - - const Expr<int>* expr; - mutable int n_; - - PluralForm::DumpList dump; //manage polymorphc object lifetimes -}; - -#endif // PARSE_PLURAL_H_INCLUDED diff --git a/shared/parse_txt.cpp b/shared/parse_txt.cpp deleted file mode 100644 index 56da3bdd..00000000 --- a/shared/parse_txt.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "parse_txt.h" - -using namespace zen; - - -namespace -{ -std::string detectLineBreak(const Zstring& filename) //throw (FileError) -{ - //read a (hopefully) significant portion of data - zen::FileInput input(filename); - - std::vector<char> buffer(64 * 1024); - size_t bytesRead = input.read(&buffer[0], buffer.size()); //throw (FileError); - buffer.resize(bytesRead); - - //detect line break - std::string linebreakChars = "\r\n"; - std::vector<char>::iterator iter = std::find_first_of(buffer.begin(), buffer.end(), - linebreakChars.begin(), linebreakChars.end()); - if (iter != buffer.end()) - { - wxString firstRow = wxString::FromUTF8(&buffer[0], iter - buffer.begin()); - - if (*iter == '\r') - { - ++iter; - if (iter != buffer.end()) - { - - if (*iter == '\n') - return "\r\n"; //Windows - else - return "\r"; //Mac - } - } - else if (*iter == '\n') - return "\n"; //Linux - } - //fallback - return "\n"; -} -} - - -ExtractLines::ExtractLines(const Zstring& filename, const std::string& lineBreak) : //throw (FileError) - inputStream(filename), bufferLogBegin(buffer.begin()), lineBreak_(lineBreak) -{ - if (lineBreak.empty()) - lineBreak_ = detectLineBreak(filename); //throw (FileError) -} - - -bool ExtractLines::getLine(std::string& output) //throw (FileError) -{ - for (;;) - { - //check if full line is in buffer - std::vector<char>::iterator iter = std::search(bufferLogBegin, buffer.end(), lineBreak_.begin(), lineBreak_.end()); - if (iter != buffer.end()) - { - output.assign(bufferLogBegin, iter); - bufferLogBegin = iter + lineBreak_.size(); - return true; - } - - buffer.erase(buffer.begin(), bufferLogBegin); - bufferLogBegin = buffer.begin(); - - //if done: cleanup - if (inputStream.eof()) - { - if (buffer.empty()) - return false; - - output.assign(buffer.begin(), buffer.end()); - buffer.clear(); - return true; - } - - //read next block - const size_t BLOCK_SIZE = 512 * 1024; - buffer.resize(buffer.size() + BLOCK_SIZE); - - size_t bytesRead = inputStream.read(&buffer[0] + buffer.size() - BLOCK_SIZE, BLOCK_SIZE); //throw (FileError); - assert(bytesRead <= BLOCK_SIZE); //promised by FileInput() - - if (bytesRead < BLOCK_SIZE) - buffer.resize(buffer.size() - (BLOCK_SIZE - bytesRead)); - - bufferLogBegin = buffer.begin(); - } -} diff --git a/shared/parse_txt.h b/shared/parse_txt.h deleted file mode 100644 index 479f950e..00000000 --- a/shared/parse_txt.h +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************** -// * 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 PARSE_TXT_H_INCLUDED -#define PARSE_TXT_H_INCLUDED - -#include "file_io.h" -#include <vector> -#include <string> - -namespace zen -{ -class ExtractLines -{ -public: - ExtractLines(const Zstring& filename, const std::string& lineBreak = std::string()); //throw FileError - bool getLine(std::string& output); //throw FileError - -private: - zen::FileInput inputStream; - std::vector<char> buffer; - std::vector<char>::iterator bufferLogBegin; - std::string lineBreak_; -}; - -} - - -#endif // PARSE_TXT_H_INCLUDED diff --git a/shared/pch.h b/shared/pch.h deleted file mode 100644 index aae74c08..00000000 --- a/shared/pch.h +++ /dev/null @@ -1,111 +0,0 @@ -// ************************************************************************** -// * 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 FFS_PRECOMPILED_HEADER -#define FFS_PRECOMPILED_HEADER - -//pay attention when using this file: might cause issues! -#ifdef NDEBUG -#error do NOT use in release build! -#endif - -#ifdef _MSC_VER -#pragma warning(disable:4996) //"warning C4996: 'std::copy': Function call with parameters that may be unsafe" -#endif - -//##################################################### -// basic wxWidgets headers -#ifndef WX_PRECOMP -#define WX_PRECOMP -#endif - -#include <wx/wxprec.h> -//#include <wx/msw/wrapwin.h> -> already included via wxprec.h - -//other wxWidgets headers -#include <wx/log.h> -#include <wx/grid.h> -#include <wx/animate.h> -#include <wx/app.h> -#include <wx/arrstr.h> -#include <wx/bitmap.h> -#include <wx/bmpbuttn.h> -#include <wx/button.h> -#include <wx/checkbox.h> -#include <wx/choice.h> -#include <wx/clipbrd.h> -#include <wx/cmdline.h> -#include <wx/colour.h> -#include <wx/config.h> -#include <wx/dc.h> -#include <wx/dialog.h> -#include <wx/dir.h> -#include <wx/dnd.h> -#include <wx/file.h> -#include <wx/filename.h> -#include <wx/filepicker.h> -#include <wx/font.h> -#include <wx/frame.h> -#include <wx/gauge.h> -#include <wx/gdicmn.h> -#include <wx/grid.h> -#include <wx/hyperlink.h> -#include <wx/icon.h> -#include <wx/image.h> -#include <wx/intl.h> -#include <wx/log.h> -#include <wx/menu.h> -#include <wx/msgdlg.h> -#include <wx/panel.h> -#include <wx/radiobut.h> -#include <wx/settings.h> -#include <wx/sizer.h> -#include <wx/statbmp.h> -#include <wx/statbox.h> -#include <wx/statline.h> -#include <wx/stattext.h> -#include <wx/stdpaths.h> -#include <wx/stopwatch.h> -#include <wx/stream.h> -#include <wx/string.h> -#include <wx/textctrl.h> -#include <wx/thread.h> -#include <wx/utils.h> -#include <wx/wfstream.h> -#include <wx/zipstrm.h> -#include <wx/scrolwin.h> -#include <wx/notebook.h> -#include <wx/help.h> -#include <wx/event.h> - -//##################################################### -// #include other rarely changing headers here - -//STL headers -#include <string> -#include <vector> -#include <set> -#include <map> -#include <queue> -#include <deque> -#include <stack> -#include <list> -#include <algorithm> -#include <functional> -#include <iterator> -#include <numeric> -#include <memory> -#include <utility> -#include <fstream> -#include <iostream> -#include <sstream> -#include <new> -#include <stdexcept> - -//Boost -#include <boost/scoped_array.hpp> - -#endif //FFS_PRECOMPILED_HEADER diff --git a/shared/perf.h b/shared/perf.h deleted file mode 100644 index 9bcf7882..00000000 --- a/shared/perf.h +++ /dev/null @@ -1,82 +0,0 @@ -// ************************************************************************** -// * 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 DEBUG_PERF_HEADER -#define DEBUG_PERF_HEADER - -#include <sstream> - -#ifdef __WXMSW__ //we have wxWidgets -#include <wx/msw/wrapwin.h> //includes "windows.h" -#else -//#define WIN32_LEAN_AND_MEAN -> not in a header -#include <windows.h> -#undef max -#undef min -#endif - - -#ifdef __MINGW32__ -#define DEPRECATED(x) x __attribute__ ((deprecated)) -#elif defined _MSC_VER -#define DEPRECATED(x) __declspec(deprecated) x -#endif - -//two macros for quick performance measurements -#define PERF_START CpuTimer perfTest; -#define PERF_STOP perfTest.showResult(); - - -class CpuTimer -{ -public: - class TimerError {}; - - DEPRECATED(CpuTimer()) : frequency(), startTime(), resultShown(false) - { - SetThreadAffinity dummy; - if (!::QueryPerformanceFrequency(&frequency)) throw TimerError(); - if (!::QueryPerformanceCounter (&startTime)) throw TimerError(); - } - - ~CpuTimer() - { - if (!resultShown) - showResult(); - } - - void showResult() - { - SetThreadAffinity dummy; - LARGE_INTEGER currentTime = {}; - if (!::QueryPerformanceCounter(¤tTime)) throw TimerError(); - - const long delta = static_cast<long>(1000.0 * (currentTime.QuadPart - startTime.QuadPart) / frequency.QuadPart); - std::ostringstream ss; - ss << delta << " ms"; - - ::MessageBoxA(NULL, ss.str().c_str(), "Timer", 0); - resultShown = true; - - if (!::QueryPerformanceCounter(&startTime)) throw TimerError(); //don't include call to MessageBox()! - } - -private: - class SetThreadAffinity - { - public: - SetThreadAffinity() : oldmask(::SetThreadAffinityMask(::GetCurrentThread(), 1)) { if (oldmask == 0) throw TimerError(); } - ~SetThreadAffinity() { ::SetThreadAffinityMask(::GetCurrentThread(), oldmask); } - private: - const DWORD_PTR oldmask; - }; - - LARGE_INTEGER frequency; - LARGE_INTEGER startTime; - bool resultShown; -}; - -#endif //DEBUG_PERF_HEADER diff --git a/shared/privilege.cpp b/shared/privilege.cpp deleted file mode 100644 index 6c7d951b..00000000 --- a/shared/privilege.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "privilege.h" -#include "last_error.h" -#include "i18n.h" -#include "loki/ScopeGuard.h" - -using namespace zen; - - -Privileges& Privileges::getInstance() -{ - static Privileges instance; - return instance; -} - - -bool Privileges::privilegeIsActive(LPCTSTR privilege) //throw FileError -{ - HANDLE hToken = NULL; - if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle, - TOKEN_QUERY, //__in DWORD DesiredAccess, - &hToken)) //__out PHANDLE TokenHandle - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hToken)); - - LUID luid = {}; - if (!::LookupPrivilegeValue( - NULL, //__in_opt LPCTSTR lpSystemName, - privilege, //__in LPCTSTR lpName, - &luid )) //__out PLUID lpLuid - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - - PRIVILEGE_SET priv = {}; - priv.PrivilegeCount = 1; - priv.Control = PRIVILEGE_SET_ALL_NECESSARY; - priv.Privilege[0].Luid = luid; - priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; - - BOOL alreadyGranted = FALSE; - if (!::PrivilegeCheck( - hToken, //__in HANDLE ClientToken, - &priv, //__inout PPRIVILEGE_SET RequiredPrivileges, - &alreadyGranted)) //__out LPBOOL pfResult - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - - return alreadyGranted == TRUE; -} - - -void Privileges::setPrivilege(LPCTSTR privilege, bool enable) //throw FileError -{ - HANDLE hToken = NULL; - if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle, - TOKEN_ADJUST_PRIVILEGES, //__in DWORD DesiredAccess, - &hToken)) //__out PHANDLE TokenHandle - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hToken)); - - LUID luid = {}; - if (!::LookupPrivilegeValue( - NULL, //__in_opt LPCTSTR lpSystemName, - privilege, //__in LPCTSTR lpName, - &luid )) //__out PLUID lpLuid - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - - 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 - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); - - if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED) //check although previous function returned with success! - throw FileError(_("Error setting privilege:") + " \"" + privilege + "\"" + "\n\n" + getLastErrorFormatted()); -} diff --git a/shared/privilege.h b/shared/privilege.h deleted file mode 100644 index 09fe0d08..00000000 --- a/shared/privilege.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef PRIVILEGE_H_INCLUDED -#define PRIVILEGE_H_INCLUDED - -#include <map> -#include "zstring.h" -#include "file_error.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" - - -namespace zen -{ -#ifdef FFS_WIN -class Privileges -{ -public: - static Privileges& getInstance(); - - void ensureActive(LPCTSTR privilege) //throw FileError - { - if (activePrivileges.find(privilege) != activePrivileges.end()) - return; //privilege already active - - if (privilegeIsActive(privilege)) //privilege was already active before starting this tool - activePrivileges.insert(std::make_pair(privilege, false)); - else - { - setPrivilege(privilege, true); - activePrivileges.insert(std::make_pair(privilege, true)); - } - } - -private: - Privileges() {} - Privileges(Privileges&); - void operator=(Privileges&); - - ~Privileges() //clean up: deactivate all privileges that have been activated by this application - { - for (PrivBuffType::const_iterator i = activePrivileges.begin(); i != activePrivileges.end(); ++i) - try - { - if (i->second) - Privileges::setPrivilege(i->first.c_str(), false); - } - catch (...) {} - } - - static bool privilegeIsActive(LPCTSTR privilege); //throw FileError - static void setPrivilege(LPCTSTR privilege, bool enable); //throw FileError - - typedef std::map<Zstring, bool> PrivBuffType; //bool: enabled by this application - - PrivBuffType activePrivileges; -}; -#endif -} - - -#endif // PRIVILEGE_H_INCLUDED diff --git a/shared/recycler.cpp b/shared/recycler.cpp deleted file mode 100644 index 8c4a9da1..00000000 --- a/shared/recycler.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// ************************************************************************** -// * 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 "recycler.h" -#include <stdexcept> -#include <iterator> -#include "i18n.h" -#include "file_handling.h" - -#ifdef FFS_WIN -#include <boost/thread/once.hpp> -#include "dll_loader.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "assert_static.h" -#include <algorithm> -#include <functional> -#include <vector> -#include "long_path_prefix.h" -#include "IFileOperation/file_op.h" - -#elif defined FFS_LINUX -#include <sys/stat.h> -#include <giomm/file.h> -#endif - -using namespace zen; - - -namespace -{ -#ifdef FFS_WIN -bool vistaOrLater() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - //IFileOperation is supported with Vista and later - if (GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5; - //XP has majorVersion == 5, minorVersion == 1 - //Vista has majorVersion == 6, minorVersion == 0 - //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} - -/* -Performance test: delete 1000 files ------------------------------------- -SHFileOperation - single file 33s -SHFileOperation - multiple files 2,1s -IFileOperation - single file 33s -IFileOperation - multiple files 2,1s - -=> SHFileOperation and IFileOperation have nearly IDENTICAL performance characteristics! - -Nevertheless, let's use IFileOperation for better error reporting! -*/ - -void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw FileError -{ - if (filesToDelete.empty()) - return; - - static bool useIFileOperation = false; - static boost::once_flag once = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(once, []() { useIFileOperation = vistaOrLater(); }); - - if (useIFileOperation) //new recycle bin usage: available since Vista - { - std::vector<const wchar_t*> fileNames; - std::transform(filesToDelete.begin(), filesToDelete.end(), - std::back_inserter(fileNames), std::mem_fun_ref(&Zstring::c_str)); - - using namespace fileop; - const util::DllFun<MoveToRecycleBinFct> moveToRecycler(getDllName(), moveToRecycleBinFctName); - const util::DllFun<GetLastErrorFct> getLastError (getDllName(), getLastErrorFctName); - - if (!moveToRecycler || !getLastError) - throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing - "\n\n" + _("Could not load a required DLL:") + " \"" + getDllName() + "\""); - - //#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(zen::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix! - - if (!moveToRecycler(&fileNames[0], //array must not be empty - fileNames.size())) - { - wchar_t errorMessage[2000]; - getLastError(errorMessage, 2000); - throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing - "\n\n" + "(" + errorMessage + ")"); - } - } - else //regular recycle bin usage: available since XP - { - Zstring filenameDoubleNull; - for (std::vector<Zstring>::const_iterator i = filesToDelete.begin(); i != filesToDelete.end(); ++i) - { - //#warning moving long file paths to recycler does not work! clarify! - //filenameDoubleNull += removeLongPathPrefix(*i); //::SHFileOperation() can't handle \\?\-prefix! - //You should use fully-qualified path names with this function. Using it with relative path names is not thread safe. - filenameDoubleNull += *i; //::SHFileOperation() can't handle \\?\-prefix! - filenameDoubleNull += L'\0'; - } - - SHFILEOPSTRUCT fileOp = {}; - fileOp.hwnd = NULL; - fileOp.wFunc = FO_DELETE; - fileOp.pFrom = filenameDoubleNull.c_str(); - fileOp.pTo = NULL; - fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - fileOp.fAnyOperationsAborted = false; - fileOp.hNameMappings = NULL; - fileOp.lpszProgressTitle = NULL; - - if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) - { - throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filenameDoubleNull + "\""); //report first file only... better than nothing - } - } -} -#endif -} - - -bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError -{ - if (!somethingExists(filename)) - return false; //neither file nor any other object with that name existing: no error situation, manual deletion relies on it! - -#ifdef FFS_WIN - //::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_NORMAL); - //both SHFileOperation and IFileOperation are not able to delete a folder named "System Volume Information" with normal attributes but shamelessly report success - - std::vector<Zstring> fileNames; - fileNames.push_back(filename); - ::moveToWindowsRecycler(fileNames); //throw FileError - -#elif defined FFS_LINUX - Glib::RefPtr<Gio::File> fileObj = Gio::File::create_for_path(filename.c_str()); //never fails - try - { - if (!fileObj->trash()) - throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filename + "\"" + - "\n\n" + "(unknown error)"); - } - catch (const Glib::Error& errorObj) - { - //implement same behavior as in Windows: if recycler is not existing, delete permanently - if (errorObj.code() == G_IO_ERROR_NOT_SUPPORTED) - { - struct stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) != 0) - return false; - - if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode)) - removeFile(filename); //throw FileError - else if (S_ISDIR(fileInfo.st_mode)) - removeDirectory(filename); //throw FileError - return true; - } - - //assemble error message - const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* ", " + - g_quark_to_string(errorObj.domain()) + */ ": " + errorObj.what(); - - throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filename + "\"" + - "\n\n" + "(" + errorMessage + ")"); - } -#endif - return true; -} - - -#ifdef FFS_WIN -zen::StatusRecycler zen::recycleBinStatus(const Zstring& pathName) -{ - std::vector<wchar_t> buffer(MAX_PATH + 1); - if (::GetVolumePathName(applyLongPathPrefix(pathName).c_str(), //__in LPCTSTR lpszFileName, - &buffer[0], //__out LPTSTR lpszVolumePathName, - static_cast<DWORD>(buffer.size()))) //__in DWORD cchBufferLength - { - Zstring rootPath = &buffer[0]; - if (!endsWith(rootPath, FILE_NAME_SEPARATOR)) //a trailing backslash is required - rootPath += FILE_NAME_SEPARATOR; - - SHQUERYRBINFO recInfo = {}; - recInfo.cbSize = sizeof(recInfo); - HRESULT rv = ::SHQueryRecycleBin(rootPath.c_str(), //__in_opt LPCTSTR pszRootPath, - &recInfo); //__inout LPSHQUERYRBINFO pSHQueryRBInfo - return rv == S_OK ? STATUS_REC_EXISTS : STATUS_REC_MISSING; - } - return STATUS_REC_UNKNOWN; -} -#elif defined FFS_LINUX -/* -We really need access to a similar function to check whether a directory supports trashing and emit a warning if it does not! - -The following function looks perfect, alas it is restricted to local files and to the implementation of GIO only: - - gboolean _g_local_file_has_trash_dir(const char* dirname, dev_t dir_dev); - See: http://www.netmite.com/android/mydroid/2.0/external/bluetooth/glib/gio/glocalfileinfo.h - - Just checking for "G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH" is not correct, since we find in - http://www.netmite.com/android/mydroid/2.0/external/bluetooth/glib/gio/glocalfileinfo.c - - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, - writable && parent_info->has_trash_dir); - - => We're NOT interested in whether the specified folder can be trashed, but whether it supports thrashing its child elements! (Only support, not actual write access!) - This renders G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH useless for this purpose. -*/ -#endif diff --git a/shared/recycler.h b/shared/recycler.h deleted file mode 100644 index 718b64cc..00000000 --- a/shared/recycler.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************** -// * 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 RECYCLER_H_INCLUDED -#define RECYCLER_H_INCLUDED - -#include "file_error.h" -#include "zstring.h" - -namespace zen -{ -/* --------------------- -|Recycle Bin Access| --------------------- - -Windows -------- -Recycler always available: during runtime either SHFileOperation or (since Vista) IFileOperation will be dynamically selected - -Linux ------ -Compiler flag: `pkg-config --cflags gtkmm-2.4` -Linker flag: `pkg-config --libs gtkmm-2.4` -*/ - -//move a file or folder to Recycle Bin (deletes permanently if recycle is not available) -bool moveToRecycleBin(const Zstring& filename); //return "true" if file/dir was actually deleted; throw (FileError) - - -#ifdef FFS_WIN -enum StatusRecycler -{ - STATUS_REC_EXISTS, - STATUS_REC_MISSING, - STATUS_REC_UNKNOWN -}; - -StatusRecycler recycleBinStatus(const Zstring& pathName); //test existence of Recycle Bin API for certain path -#endif -} - -#endif // RECYCLER_H_INCLUDED diff --git a/shared/resolve_path.cpp b/shared/resolve_path.cpp deleted file mode 100644 index f22b4505..00000000 --- a/shared/resolve_path.cpp +++ /dev/null @@ -1,544 +0,0 @@ -#include "resolve_path.h" -#include <wx/utils.h> -#include <wx/datetime.h> -#include "string_conv.h" -#include "loki/ScopeGuard.h" -#include <map> - -#ifdef FFS_WIN -#include "dll_loader.h" -#include <Shlobj.h> -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "long_path_prefix.h" -#ifdef _MSC_VER -#pragma comment(lib, "Mpr.lib") -#endif - -#elif defined FFS_LINUX -#include <map> -#include "file_traverser.h" -#include "stdlib.h" -#endif - -using namespace zen; - - -namespace -{ -#ifdef FFS_WIN -Zstring resolveBrokenNetworkMap(const Zstring& dirname) //circumvent issue with disconnected network maps that could be activated by a simple explorer double click -{ - /* - ATTENTION: it is not safe to call ::WNetGetConnection() for every network share: - - network type |::WNetGetConnection rv | lpRemoteName | existing UNC path - -----------------------------|-------------------------|---------------------------------|---------------- - inactive local network share | ERROR_CONNECTION_UNAVAIL| \\192.168.1.27\new2 | YES - WebDrive | NO_ERROR | \\Webdrive-ZenJu\GNU | NO - Box.net (WebDav) | NO_ERROR | \\www.box.net\DavWWWRoot\dav | YES - NetDrive | ERROR_NOT_CONNECTED | <empty> | NO - */ - - if (dirname.size() >= 2 && iswalpha(dirname[0]) && dirname[1] == L':') - { - Zstring driveLetter(dirname.c_str(), 2); //e.g.: "Q:" - - //if (::GetFileAttributes((driveLetter + L'\\').c_str()) == INVALID_FILE_ATTRIBUTES) <- this will seriously block if network is not reachable!!! - { - DWORD bufferSize = 10000; - std::vector<wchar_t> remoteNameBuffer(bufferSize); - DWORD rv = ::WNetGetConnection(driveLetter.c_str(), //__in LPCTSTR lpLocalName in the form "<driveletter>:" - &remoteNameBuffer[0], //__out LPTSTR lpRemoteName, - &bufferSize); //__inout LPDWORD lpnLength - if (rv == ERROR_CONNECTION_UNAVAIL) //remoteNameBuffer will be filled nevertheless! - { - Zstring networkShare = &remoteNameBuffer[0]; - if (!networkShare.empty()) - return networkShare + (dirname.c_str() + 2); //replace "Q:\subdir" by "\\server\share\subdir" - } - } - } - return dirname; -} - - -Zstring resolveRelativePath(Zstring relativeName) -{ - relativeName = resolveBrokenNetworkMap(relativeName); - - std::vector<Zchar> fullPath(10000); - - const DWORD rv = ::GetFullPathName(applyLongPathPrefix(relativeName).c_str(), //__in LPCTSTR lpFileName, - static_cast<DWORD>(fullPath.size()), //__in DWORD nBufferLength, - &fullPath[0], //__out LPTSTR lpBuffer, - NULL); //__out LPTSTR *lpFilePart - if (rv == 0 || rv >= fullPath.size()) //theoretically, rv can never be == fullPath.size() - //ERROR! Don't do anything - return relativeName; - - return &fullPath[0]; -} - -#elif defined FFS_LINUX -Zstring resolveRelativePath(const Zstring& relativeName) //additional: resolves symbolic links!!! -{ - char absolutePath[PATH_MAX + 1]; - if (::realpath(relativeName.c_str(), absolutePath) == NULL) - //ERROR! Don't do anything - return relativeName; - - return Zstring(absolutePath); -} -#endif - - -#ifdef FFS_WIN -class CsidlConstants -{ -public: - typedef std::map<Zstring, Zstring, LessFilename> CsidlToDirMap; //case-insensitive comparison - - static const CsidlToDirMap& get() - { - static CsidlConstants inst; - return inst.csidlToDir; - } - -private: - CsidlConstants() - { - auto addCsidl = [&](int csidl, const Zstring& paramName) - { - wchar_t buffer[MAX_PATH]; - if (SUCCEEDED(::SHGetFolderPath(NULL, //__in HWND hwndOwner, - csidl | CSIDL_FLAG_DONT_VERIFY, //__in int nFolder, - NULL, //__in HANDLE hToken, - 0 /* == SHGFP_TYPE_CURRENT*/, //__in DWORD dwFlags, - buffer))) //__out LPTSTR pszPath - { - Zstring dirname = buffer; - if (!dirname.empty()) - csidlToDir.insert(std::make_pair(paramName, dirname)); - } - }; - - addCsidl(CSIDL_DESKTOPDIRECTORY, L"csidl_Desktop"); // C:\Users\username\Desktop - addCsidl(CSIDL_COMMON_DESKTOPDIRECTORY, L"csidl_PublicDesktop"); // C:\Users\All Users\Desktop - - addCsidl(CSIDL_MYMUSIC, L"csidl_MyMusic"); // C:\Users\username\My Documents\My Music - addCsidl(CSIDL_COMMON_MUSIC, L"csidl_PublicMusic"); // C:\Users\All Users\Documents\My Music - - addCsidl(CSIDL_MYPICTURES, L"csidl_MyPictures"); // C:\Users\username\My Documents\My Pictures - addCsidl(CSIDL_COMMON_PICTURES, L"csidl_PublicPictures"); // C:\Users\All Users\Documents\My Pictures - - addCsidl(CSIDL_MYVIDEO, L"csidl_MyVideo"); // C:\Users\username\My Documents\My Videos - addCsidl(CSIDL_COMMON_VIDEO, L"csidl_PublicVideo"); // C:\Users\All Users\Documents\My Videos - - addCsidl(CSIDL_PERSONAL, L"csidl_MyDocuments"); // C:\Users\username\My Documents - addCsidl(CSIDL_COMMON_DOCUMENTS, L"csidl_PublicDocuments"); // C:\Users\All Users\Documents - - addCsidl(CSIDL_STARTMENU, L"csidl_StartMenu"); // C:\Users\username\Start Menu - addCsidl(CSIDL_COMMON_STARTMENU, L"csidl_PublicStartMenu"); // C:\Users\All Users\Start Menu - - addCsidl(CSIDL_FAVORITES, L"csidl_Favorites"); // C:\Users\username\Favorites - addCsidl(CSIDL_COMMON_FAVORITES, L"csidl_PublicFavorites"); // C:\Users\All Users\Favoriten - - addCsidl(CSIDL_TEMPLATES, L"csidl_Templates"); // C:\Users\username\Templates - addCsidl(CSIDL_COMMON_TEMPLATES, L"csidl_PublicTemplates"); // C:\Users\All Users\Templates - - addCsidl(CSIDL_RESOURCES, L"csidl_Resources"); // C:\Windows\Resources - - //CSIDL_APPDATA covered by %AppData% - //CSIDL_LOCAL_APPDATA covered by %LocalAppData% - //CSIDL_COMMON_APPDATA covered by %ProgramData% - - //CSIDL_PROFILE covered by %UserProfile% - } - - CsidlConstants(const CsidlConstants&); - CsidlConstants& operator=(const CsidlConstants&); - - CsidlToDirMap csidlToDir; -}; -#endif - - -wxString getEnvValue(const wxString& envName) //return empty on error -{ - //try to apply environment variables - wxString envValue; - if (wxGetEnv(envName, &envValue)) - { - //some postprocessing: - trim(envValue); //remove leading, trailing blanks - - //remove leading, trailing double-quotes - if (startsWith(envValue, L"\"") && - endsWith(envValue, L"\"") && - envValue.length() >= 2) - envValue = wxString(envValue.c_str() + 1, envValue.length() - 2); - } - return envValue; -} - - -bool replaceMacro(wxString& macro) //macro without %-characters, return true if replaced successfully -{ - if (macro.IsEmpty()) - return false; - - //there are equally named environment variables %TIME%, %DATE% existing, so replace these first! - if (macro.CmpNoCase(wxT("time")) == 0) - { - macro = wxDateTime::Now().FormatISOTime(); - macro.Replace(wxT(":"), wxT("")); - return true; - } - - if (macro.CmpNoCase(wxT("date")) == 0) - { - macro = wxDateTime::Now().FormatISODate(); - return true; - } - - auto processPhrase = [&](const wchar_t* phrase, const wchar_t* format) -> bool - { - if (macro.CmpNoCase(phrase) != 0) - return false; - macro = wxDateTime::Now().Format(format); - return true; - }; - - if (processPhrase(L"weekday", L"%A")) return true; - if (processPhrase(L"day" , L"%d")) return true; - if (processPhrase(L"month" , L"%B")) return true; - if (processPhrase(L"week" , L"%U")) return true; - if (processPhrase(L"year" , L"%Y")) return true; - if (processPhrase(L"hour" , L"%H")) return true; - if (processPhrase(L"min" , L"%M")) return true; - if (processPhrase(L"sec" , L"%S")) return true; - - //try to apply environment variables - { - wxString envValue = getEnvValue(macro); - if (!envValue.empty()) - { - macro = envValue; - return true; - } - } - -#ifdef FFS_WIN - //try to resolve CSIDL values - { - auto csidlMap = CsidlConstants::get(); - auto iter = csidlMap.find(toZ(macro)); - if (iter != csidlMap.end()) - { - macro = toWx(iter->second); - return true; - } - } -#endif - - return false; -} - - -void expandMacros(wxString& text) -{ - const wxChar SEPARATOR = '%'; - - if (text.Find(SEPARATOR) != wxNOT_FOUND) - { - wxString prefix = text.BeforeFirst(SEPARATOR); - wxString postfix = text.AfterFirst(SEPARATOR); - if (postfix.Find(SEPARATOR) != wxNOT_FOUND) - { - wxString potentialMacro = postfix.BeforeFirst(SEPARATOR); - wxString rest = postfix.AfterFirst(SEPARATOR); //text == prefix + SEPARATOR + potentialMacro + SEPARATOR + rest - - if (replaceMacro(potentialMacro)) - { - expandMacros(rest); - text = prefix + potentialMacro + rest; - } - else - { - rest = SEPARATOR + rest; - expandMacros(rest); - text = prefix + SEPARATOR + potentialMacro + rest; - } - } - } -} - - -#ifdef FFS_LINUX -class TraverseMedia : public zen::TraverseCallback -{ -public: - typedef std::map<Zstring, Zstring> DeviceList; //device name -> device path mapping - - TraverseMedia(DeviceList& devices) : devices_(devices) {} - - virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {} - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} - virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) - { - devices_.insert(std::make_pair(shortName, fullName)); - return Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); //DON'T traverse into subdirs - } - virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } - -private: - DeviceList& devices_; -}; -#endif - - -Zstring volumenNameToPath(const Zstring& volumeName) //return empty string on error -{ -#ifdef FFS_WIN - std::vector<wchar_t> volGuid(10000); - - HANDLE hVol = ::FindFirstVolume(&volGuid[0], static_cast<DWORD>(volGuid.size())); - if (hVol != INVALID_HANDLE_VALUE) - { - LOKI_ON_BLOCK_EXIT2(::FindVolumeClose(hVol)); - - do - { - std::vector<wchar_t> volName(MAX_PATH + 1); - - if (::GetVolumeInformation(&volGuid[0], //__in_opt LPCTSTR lpRootPathName, - &volName[0], //__out LPTSTR lpVolumeNameBuffer, - static_cast<DWORD>(volName.size()), //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, - 0)) //__in DWORD nFileSystemNameSize - { - if (EqualFilename()(volumeName, Zstring(&volName[0]))) - { - //GetVolumePathNamesForVolumeName is not available for Windows 2000! - typedef BOOL (WINAPI *GetVolumePathNamesForVolumeNameWFunc)(LPCWSTR lpszVolumeName, - LPWCH lpszVolumePathNames, - DWORD cchBufferLength, - PDWORD lpcchReturnLength); - - const util::DllFun<GetVolumePathNamesForVolumeNameWFunc> getVolumePathNamesForVolumeName(L"kernel32.dll", "GetVolumePathNamesForVolumeNameW"); - if (getVolumePathNamesForVolumeName) - { - std::vector<wchar_t> volPath(10000); - - DWORD returnedLen = 0; - if (getVolumePathNamesForVolumeName(&volGuid[0], //__in LPCTSTR lpszVolumeName, - &volPath[0], //__out LPTSTR lpszVolumePathNames, - static_cast<DWORD>(volPath.size()), //__in DWORD cchBufferLength, - &returnedLen)) //__out PDWORD lpcchReturnLength - { - return &volPath[0]; //return first path name in double-null terminated list! - } - } - return &volGuid[0]; //GUID looks ugly, but should be working correctly - } - } - } - while (::FindNextVolume(hVol, &volGuid[0], static_cast<DWORD>(volGuid.size()))); - } - -#elif defined FFS_LINUX - //due to the naming convention on Linux /media/<volume name> this function is not that useful, but... - - TraverseMedia::DeviceList deviceList; - - TraverseMedia traverser(deviceList); - traverseFolder("/media", false, traverser); //traverse one level - - TraverseMedia::DeviceList::const_iterator iter = deviceList.find(volumeName); - if (iter != deviceList.end()) - return iter->second; -#endif - return Zstring(); -} - - -#ifdef FFS_WIN -Zstring volumePathToName(const Zstring& volumePath) //return empty string on error -{ - const DWORD bufferSize = MAX_PATH + 1; - std::vector<wchar_t> volName(bufferSize); - - if (::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - &volName[0], //__out LPTSTR lpVolumeNameBuffer, - bufferSize, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, - 0)) //__in DWORD nFileSystemNameSize - { - return &volName[0]; - } - return Zstring(); -} -#endif - - -void expandVolumeName(Zstring& text) // [volname]:\folder [volname]\folder [volname]folder -> C:\folder -{ - Zstring before; - Zstring volname; - Zstring after; - - size_t posStart = text.find(Zstr("[")); - if (posStart != Zstring::npos) - { - size_t posEnd = text.find(Zstr("]"), posStart); - if (posEnd != Zstring::npos) - { - before = Zstring(text.c_str(), posStart); - volname = Zstring(text.c_str() + posStart + 1, posEnd - posStart - 1); - after = Zstring(text.c_str() + posEnd + 1); - - if (startsWith(after, ':')) - after = afterFirst(after, ':'); - if (startsWith(after, FILE_NAME_SEPARATOR)) - after = afterFirst(after, FILE_NAME_SEPARATOR); - } - } - - if (volname.empty()) - return; - - Zstring volPath = volumenNameToPath(volname); //return empty string on error - if (volPath.empty()) - return; - - if (!volPath.EndsWith(FILE_NAME_SEPARATOR)) - volPath += FILE_NAME_SEPARATOR; - - text = before + volPath + after; -} -} - - -#ifdef FFS_WIN -std::vector<Zstring> zen::getDirectoryAliases(Zstring dirname) -{ - trim(dirname, true, false); - - std::vector<Zstring> output; - - if (dirname.empty()) - return output; - - //1. replace volume path by volume name: c:\dirname -> [SYSTEM]\dirname - if (dirname.size() >= 3 && - std::iswalpha(dirname[0]) && - dirname[1] == L':' && - dirname[2] == L'\\') - { - Zstring volname = volumePathToName(Zstring(dirname.c_str(), 3)); - if (!volname.empty()) - output.push_back(L"[" + volname + L"]" + Zstring(dirname.c_str() + 2)); - } - - //2. replace volume name by volume path: [SYSTEM]\dirname -> c:\dirname - { - Zstring testVolname = dirname; - expandVolumeName(testVolname); - if (testVolname != dirname) - output.push_back(testVolname); - } - - //3. environment variables: C:\Users\username -> %USERPROFILE% - { - std::map<Zstring, Zstring> envToDir; - - //get list of useful variables - auto addEnvVar = [&](const wxString& envName) - { - wxString envVal = getEnvValue(envName); //return empty on error - if (!envVal.empty()) - envToDir.insert(std::make_pair(toZ(envName), toZ(envVal))); - }; - addEnvVar(L"AllUsersProfile"); // C:\ProgramData - addEnvVar(L"AppData"); // C:\Users\username\AppData\Roaming - addEnvVar(L"LocalAppData"); // C:\Users\username\AppData\Local - addEnvVar(L"ProgramData"); // C:\ProgramData - addEnvVar(L"ProgramFiles"); // C:\Program Files - addEnvVar(L"ProgramFiles(x86)");// C:\Program Files (x86) - addEnvVar(L"Public"); // C:\Users\Public - addEnvVar(L"UserProfile"); // C:\Users\username - addEnvVar(L"WinDir"); // C:\Windows - addEnvVar(L"Temp"); // C:\Windows\Temp - - //add CSIDL values: http://msdn.microsoft.com/en-us/library/bb762494(v=vs.85).aspx - auto csidlMap = CsidlConstants::get(); - envToDir.insert(csidlMap.begin(), csidlMap.end()); - - Zstring tmp = dirname; - ::makeUpper(tmp); - std::for_each(envToDir.begin(), envToDir.end(), - [&](const std::pair<Zstring, Zstring>& entry) - { - Zstring tmp2 = entry.second; //case-insensitive "startsWith()" - ::makeUpper(tmp2); // - if (startsWith(tmp, tmp2)) - output.push_back(L"%" + entry.first + L"%" + (dirname.c_str() + tmp2.size())); - }); - } - - //5. replace (all) macros: //%USERPROFILE% -> C:\Users\username - { - wxString testMacros = toWx(dirname); - expandMacros(testMacros); - if (toZ(testMacros) != dirname) - output.push_back(toZ(testMacros)); - } - - return output; -} -#endif - - -Zstring zen::getFormattedDirectoryName(const Zstring& dirname) -{ - //Formatting is needed since functions expect the directory to end with '\' to be able to split the relative names. - //note: don't combine directory formatting with wxFileName, as it doesn't respect //?/ - prefix! - - wxString dirnameTmp = toWx(dirname); - expandMacros(dirnameTmp); - - Zstring output = toZ(dirnameTmp); - - expandVolumeName(output); - - //remove leading/trailing whitespace - trim(output, true, false); - while (endsWith(output, " ")) //don't remove all whitespace from right, e.g. 0xa0 may be used as part of dir name - output.resize(output.size() - 1); - - if (output.empty()) //an empty string will later be returned as "\"; this is not desired - return Zstring(); - - /* - resolve relative names; required by: - WINDOWS: - - \\?\-prefix which needs absolute names - - Volume Shadow Copy: volume name needs to be part of each filename - - file icon buffer (at least for extensions that are actually read from disk, e.g. "exe") - - ::SHFileOperation(): Using relative path names is not thread safe - WINDOWS/LINUX: - - detection of dependent directories, e.g. "\" and "C:\test" - */ - output = resolveRelativePath(output); - - if (!output.EndsWith(FILE_NAME_SEPARATOR)) - output += FILE_NAME_SEPARATOR; - - return output; -} diff --git a/shared/resolve_path.h b/shared/resolve_path.h deleted file mode 100644 index 3be1d78e..00000000 --- a/shared/resolve_path.h +++ /dev/null @@ -1,24 +0,0 @@ -// ************************************************************************** -// * 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 RESOLVE_PATH_H_INCLUDED -#define RESOLVE_PATH_H_INCLUDED - -#include "zstring.h" - - -namespace zen -{ -Zstring getFormattedDirectoryName(const Zstring& dirname); - - -#ifdef FFS_WIN -std::vector<Zstring> getDirectoryAliases(Zstring dirname); -#endif -} - - -#endif // RESOLVE_PATH_H_INCLUDED diff --git a/shared/serialize.cpp b/shared/serialize.cpp deleted file mode 100644 index 06d409df..00000000 --- a/shared/serialize.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************** -// * 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 "serialize.h" -#include "i18n.h" - -using namespace zen; - - -void ReadInputStream::throwReadError() const //throw FileError -{ - throw zen::FileError(_("Error reading from synchronization database:") + " \n" + "\"" + errorObjName_.c_str() + "\""); -} - - -ReadInputStream::CharArray ReadInputStream::readArrayC() const -{ - const boost::uint32_t byteCount = readNumberC<boost::uint32_t>(); - CharArray buffer(new std::vector<char>(byteCount)); - if (byteCount > 0) - { - stream_.Read(&(*buffer)[0], byteCount); - check(); - if (stream_.LastRead() != byteCount) //some additional check - throwReadError(); - } - return buffer; -} - - -//-------------------------------------------------------------------------------------------------------- -void WriteOutputStream::throwWriteError() const //throw FileError -{ - throw zen::FileError(_("Error writing to synchronization database:") + " \n" + "\"" + errorObjName_.c_str() + "\""); -} - - -void WriteOutputStream::writeArrayC(const std::vector<char>& buffer) const -{ - writeNumberC<boost::uint32_t>(static_cast<boost::uint32_t>(buffer.size())); - if (buffer.size() > 0) - { - stream_.Write(&buffer[0], buffer.size()); - check(); - if (stream_.LastWrite() != buffer.size()) //some additional check - throwWriteError(); - } -} diff --git a/shared/serialize.h b/shared/serialize.h deleted file mode 100644 index 6930bcb9..00000000 --- a/shared/serialize.h +++ /dev/null @@ -1,260 +0,0 @@ -// ************************************************************************** -// * 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 SERIALIZE_H_INCLUDED -#define SERIALIZE_H_INCLUDED - -#include <vector> -#include "file_error.h" -#include <wx/stream.h> -#include <memory> -#include <boost/cstdint.hpp> -#include "file_io.h" - - -namespace zen -{ -//unchecked, unformatted serialization -template <class T> T readPOD (wxInputStream& stream); -template <class T> void writePOD(wxOutputStream& stream, const T& pod); - -template <class S> S readString (wxInputStream& stream); -template <class S> void writeString(wxOutputStream& stream, const S& str); - - -//############# wxWidgets stream adapter ############# -// can be used as base classes (have virtual destructors) -class FileInputStream : public wxInputStream -{ -public: - FileInputStream(const Zstring& filename) : //throw FileError - fileObj(filename) {} - -private: - virtual size_t OnSysRead(void* buffer, size_t bufsize) - { - return fileObj.read(buffer, bufsize); //throw FileError - } - - zen::FileInput fileObj; -}; - - -class FileOutputStream : public wxOutputStream -{ -public: - FileOutputStream(const Zstring& filename) : //throw FileError - fileObj(filename, zen::FileOutput::ACC_OVERWRITE) {} - -private: - virtual size_t OnSysWrite(const void* buffer, size_t bufsize) - { - fileObj.write(buffer, bufsize); //throw FileError - return bufsize; - } - - zen::FileOutput fileObj; -}; - - - -class ReadInputStream //throw FileError -{ -protected: - ReadInputStream(wxInputStream& stream, const wxString& errorObjName) : stream_(stream), errorObjName_(errorObjName) {} - - template <class T> - T readNumberC() const; //throw FileError, checked read operation - - template <class S> - S readStringC() const; //throw FileError, checked read operation - - typedef std::shared_ptr<std::vector<char> > CharArray; //there's no guarantee std::string has a ref-counted implementation... so use this "thing" - CharArray readArrayC() const; //throw FileError - - void check() const; - - wxInputStream& getStream() - { - return stream_; - } - -private: - wxInputStream& stream_; - void throwReadError() const; //throw FileError - const wxString& errorObjName_; //used for error text only -}; - - -class WriteOutputStream //throw FileError -{ -protected: - WriteOutputStream(const wxString& errorObjName, wxOutputStream& stream) : stream_(stream), errorObjName_(errorObjName) {} - - template <class T> - void writeNumberC(T number) const; //throw FileError, checked write operation - - template <class S> - void writeStringC(const S& str) const; //throw FileError, checked write operation - - void writeArrayC(const std::vector<char>& buffer) const; //throw FileError - - void check() const; - - wxOutputStream& getStream() - { - return stream_; - } - -private: - wxOutputStream& stream_; - void throwWriteError() const; //throw FileError - const wxString& errorObjName_; //used for error text only! -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//---------------Inline Implementation--------------------------------------------------- -template <class T> -inline -T readPOD(wxInputStream& stream) -{ - T pod = 0; - stream.Read(reinterpret_cast<char*>(&pod), sizeof(T)); - return pod; -} - - -template <class T> -inline -void writePOD(wxOutputStream& stream, const T& pod) -{ - stream.Write(reinterpret_cast<const char*>(&pod), sizeof(T)); -} - - -template <class S> -inline -S readString(wxInputStream& stream) -{ - typedef typename S::value_type CharType; - - const auto strLength = readPOD<boost::uint32_t>(stream); - if (strLength <= 1000) - { - CharType buffer[1000]; - stream.Read(buffer, sizeof(CharType) * strLength); - return S(buffer, strLength); - } - else - { - std::vector<CharType> buffer(strLength); //throw std::bad_alloc - stream.Read(&buffer[0], sizeof(CharType) * strLength); - return S(&buffer[0], strLength); - } -} - - -template <class S> -inline -void writeString(wxOutputStream& stream, const S& str) -{ - writePOD(stream, static_cast<boost::uint32_t>(str.length())); - stream.Write(str.c_str(), sizeof(typename S::value_type) * str.length()); -} - - -inline -void ReadInputStream::check() const -{ - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throwReadError(); -} - - -template <class T> -inline -T ReadInputStream::readNumberC() const //checked read operation -{ - T output = readPOD<T>(stream_); - check(); - return output; -} - - -template <class S> -inline -S ReadInputStream::readStringC() const //checked read operation -{ - S output; - try - { - output = readString<S>(stream_); //throw (std::bad_alloc) - check(); - } - catch (std::exception&) - { - throwReadError(); - } - return output; -} - - -template <class T> -inline -void WriteOutputStream::writeNumberC(T number) const //checked write operation -{ - writePOD<T>(stream_, number); - check(); -} - - -template <class S> -inline -void WriteOutputStream::writeStringC(const S& str) const //checked write operation -{ - writeString(stream_, str); - check(); -} - - - -inline -void WriteOutputStream::check() const -{ - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throwWriteError(); -} - -} - -#endif //SERIALIZE_H_INCLUDED diff --git a/shared/shadow.cpp b/shared/shadow.cpp deleted file mode 100644 index 7f25076e..00000000 --- a/shared/shadow.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// ************************************************************************** -// * 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 "shadow.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "i18n.h" -#include "dll_loader.h" -#include <stdexcept> -#include "assert_static.h" -#include "build_info.h" -#include "ShadowCopy\shadow.h" -#include "Loki/ScopeGuard.h" - -using namespace zen; -using namespace shadow; - - -namespace -{ -bool runningWOW64() //test if process is running under WOW64 (reference http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx) -{ - //dynamically load windows API function - typedef BOOL (WINAPI *IsWow64ProcessFun)(HANDLE hProcess, PBOOL Wow64Process); - - const util::DllFun<IsWow64ProcessFun> isWow64Process(L"kernel32.dll", "IsWow64Process"); - if (isWow64Process) - { - BOOL isWow64 = FALSE; - if (isWow64Process(::GetCurrentProcess(), &isWow64)) - return isWow64 == TRUE; - } - - return false; -} -} - -//############################################################################################################# - - -class ShadowCopy::ShadowVolume -{ -public: - ShadowVolume(const Zstring& volumeNameFormatted) : //throw(FileError) - createShadowCopy(getDllName(), createShadowCopyFctName), - releaseShadowCopy(getDllName(), releaseShadowCopyFctName), - backupHandle(0) - { - //check if shadow copy dll was loaded correctly - if (!createShadowCopy || !releaseShadowCopy) - throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\n" + - _("Could not load a required DLL:") + " \"" + getDllName() + "\""); - - //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003 - //(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx) - if (runningWOW64()) - throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\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)) - throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\n" + - "(" + errorMessage + " Volume: \"" + volumeNameFormatted + "\")"); - - shadowVol = Zstring(shadowVolName) + FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash - } - - ~ShadowVolume() - { - releaseShadowCopy(backupHandle); //fast! no performance optimization necessary - } - - Zstring getShadowVolume() const //trailing path separator - { - return shadowVol; - } - -private: - ShadowVolume(const ShadowVolume&); - ShadowVolume& operator=(const ShadowVolume&); - - const util::DllFun<CreateShadowCopyFct> createShadowCopy; - const util::DllFun<ReleaseShadowCopyFct> releaseShadowCopy; - - Zstring shadowVol; - - ShadowHandle backupHandle; -}; -//############################################################################################################# - - -Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) -{ - wchar_t volumeNameRaw[1000]; - - if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName, - volumeNameRaw, //__out LPTSTR lpszVolumePathName, - 1000)) //__in DWORD cchBufferLength - throw FileError(_("Could not determine volume name for file:") + "\n\"" + inputFile + "\""); - - Zstring volumeNameFormatted = volumeNameRaw; - if (!volumeNameFormatted.EndsWith(FILE_NAME_SEPARATOR)) - volumeNameFormatted += FILE_NAME_SEPARATOR; - - //input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found. - const size_t pos = inputFile.find(volumeNameFormatted); //inputFile needs NOT to begin with volumeNameFormatted: consider for example \\?\ prefix! - if (pos == Zstring::npos) - { - std::wstring msg = _("Volume name %x not part of filename %y!"); - replace(msg, L"%x", std::wstring(L"\"") + volumeNameFormatted + "\"", false); - replace(msg, L"%y", std::wstring(L"\"") + inputFile + "\"", false); - throw FileError(msg); - } - - //get or create instance of shadow volume - VolNameShadowMap::const_iterator iter = shadowVol.find(volumeNameFormatted); - if (iter == shadowVol.end()) - { - std::shared_ptr<ShadowVolume> newEntry(new ShadowVolume(volumeNameFormatted)); - iter = shadowVol.insert(std::make_pair(volumeNameFormatted, newEntry)).first; - } - - //return filename alias on shadow copy volume - return iter->second->getShadowVolume() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length()); -} diff --git a/shared/shadow.h b/shared/shadow.h deleted file mode 100644 index aff5b437..00000000 --- a/shared/shadow.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************** -// * 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 SHADOW_H_INCLUDED -#define SHADOW_H_INCLUDED - -#ifndef FFS_WIN -use in windows build only! -#endif - -#include "zstring.h" -#include "file_error.h" -#include <map> -#include <memory> - - -namespace shadow -{ -class ShadowCopy //buffer access to Windows Volume Shadow Copy Service -{ -public: - ShadowCopy() {} - - Zstring makeShadowCopy(const Zstring& inputFile); //throw(FileError); returns filename on shadow copy - -private: - ShadowCopy(const ShadowCopy&); - ShadowCopy& operator=(const ShadowCopy&); - - class ShadowVolume; - typedef std::map<Zstring, std::shared_ptr<ShadowVolume>, LessFilename> VolNameShadowMap; - VolNameShadowMap shadowVol; -}; -} - -#endif // SHADOW_H_INCLUDED diff --git a/shared/shell_execute.h b/shared/shell_execute.h deleted file mode 100644 index a127ee06..00000000 --- a/shared/shell_execute.h +++ /dev/null @@ -1,115 +0,0 @@ -// ************************************************************************** -// * 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 EXECUTE_HEADER_23482134578134134 -#define EXECUTE_HEADER_23482134578134134 - -#include <wx/msgdlg.h> - -#ifdef FFS_WIN -#include "last_error.h" -#include "string_tools.h" -#include "i18n.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" - -#elif defined FFS_LINUX -#include <stdlib.h> -#include <wx/utils.h> -#endif - - -namespace zen -{ -//launch commandline and report errors via popup dialog -//windows: COM needs to be initialized before calling this function! -namespace -{ -enum ExecutionType -{ - EXEC_TYPE_SYNC, - EXEC_TYPE_ASYNC -}; - -void shellExecute(const wxString& command, ExecutionType type = EXEC_TYPE_ASYNC) -{ -#ifdef FFS_WIN - //parse commandline - std::vector<std::wstring> argv; - { - int argc = 0; - LPWSTR* tmp = ::CommandLineToArgvW(command.c_str(), &argc); - for (int i = 0; i < argc; ++i) - argv.push_back(tmp[i]); - ::LocalFree(tmp); - } - - wxString filename; - wxString arguments; - if (!argv.empty()) - { - filename = argv[0]; - for (std::vector<std::wstring>::const_iterator i = argv.begin() + 1; i != argv.end(); ++i) - arguments += (i != argv.begin() ? L" " : L"") + - (i->empty() || std::find_if(i->begin(), i->end(), &cStringIsWhiteSpace<wchar_t>) != i->end() ? L"\"" + *i + L"\"" : *i); - } - - SHELLEXECUTEINFO execInfo = {}; - execInfo.cbSize = sizeof(execInfo); - - //SEE_MASK_NOASYNC is equal to SEE_MASK_FLAG_DDEWAIT, but former is defined not before Win SDK 6.0 - execInfo.fMask = type == EXEC_TYPE_SYNC ? (SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT) : 0; //don't use SEE_MASK_ASYNCOK -> returns successful despite errors! - execInfo.fMask |= SEE_MASK_UNICODE | SEE_MASK_FLAG_NO_UI; //::ShellExecuteEx() shows a non-blocking pop-up dialog on errors -> we want a blocking one - execInfo.lpVerb = L"open"; - execInfo.lpFile = filename.c_str(); - execInfo.lpParameters = arguments.c_str(); - execInfo.nShow = SW_SHOWNORMAL; - - if (!::ShellExecuteEx(&execInfo)) //__inout LPSHELLEXECUTEINFO lpExecInfo - { - wxString errorMsg = _("Invalid command line: %x"); - wxString cmdFmt = wxString(L"\nFile: ") + filename + L"\nArg: " + arguments; - - errorMsg.Replace(L"%x", cmdFmt); - wxMessageBox(errorMsg + L"\n\n" + getLastErrorFormatted()); - return; - } - - if (type == EXEC_TYPE_SYNC) - { - if (execInfo.hProcess != 0) - { - ::WaitForSingleObject(execInfo.hProcess, INFINITE); - ::CloseHandle(execInfo.hProcess); - } - } - -#elif defined FFS_LINUX - if (type == EXEC_TYPE_SYNC) - { - int rv = ::system(utf8CvrtTo<std::string>(command).c_str()); //do NOT use std::system as its documentation says nothing about "WEXITSTATUS(rv)", ect... - if (rv == -1 || WEXITSTATUS(rv) == 127) //http://linux.die.net/man/3/system "In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127)" - { - wxString errorMsg = _("Invalid command line: %x"); - replace(errorMsg, L"%x", L"\n" + command); - wxMessageBox(errorMsg); - return; - } - } - else - { - // ! unfortunately it seems there is no way on Linux to get a failure notification for calling an invalid command line asynchronously ! - - //by default wxExecute uses a zero sized dummy window as a hack to keep focus which leaves a useless empty icon in ALT-TAB list - //=> use wxEXEC_NODISABLE and roll our own window disabler! (see comment in app.cpp: void *wxGUIAppTraits::BeforeChildWaitLoop()) - wxWindowDisabler dummy; //disables all top level windows - wxExecute(command, wxEXEC_ASYNC | wxEXEC_NODISABLE); - } -#endif -} -} -} - -#endif //EXECUTE_HEADER_23482134578134134 diff --git a/shared/standard_paths.cpp b/shared/standard_paths.cpp deleted file mode 100644 index c2d79516..00000000 --- a/shared/standard_paths.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************** -// * 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 "standard_paths.h" -#include <wx/stdpaths.h> -#include "string_conv.h" - -using namespace zen; - - -namespace -{ -const wxString& getBinaryDir() //directory containing executable WITH path separator at end -{ - static wxString instance = beforeLast(wxStandardPaths::Get().GetExecutablePath(), FILE_NAME_SEPARATOR) + toWx(Zstring(FILE_NAME_SEPARATOR)); - return instance; -} - -#ifdef FFS_WIN -wxString getInstallDir() //root install directory WITH path separator at end -{ - return getBinaryDir().BeforeLast(FILE_NAME_SEPARATOR).BeforeLast(FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR; -} -#endif -} - - -bool zen::isPortableVersion() -{ -#ifdef FFS_WIN - static const bool isPortable = !wxFileExists(getInstallDir() + wxT("uninstall.exe")); //this check is a bit lame... -#elif defined FFS_LINUX - static const bool isPortable = !::getBinaryDir().EndsWith(wxT("/bin/")); //this check is a bit lame... -#endif - return isPortable; -} - - -wxString zen::getResourceDir() -{ -#ifdef FFS_WIN - return getInstallDir(); -#elif defined FFS_LINUX - if (isPortableVersion()) - return getBinaryDir(); - else //use OS' standard paths - { - wxString resourceDir = wxStandardPathsBase::Get().GetResourcesDir(); - - if (!endsWith(resourceDir, FILE_NAME_SEPARATOR)) - resourceDir += FILE_NAME_SEPARATOR; - - return resourceDir; - } -#endif -} - - -wxString zen::getConfigDir() -{ - if (isPortableVersion()) -#ifdef FFS_WIN - return getInstallDir(); -#elif defined FFS_LINUX - //wxString(wxT(".")) + zToWx(FILE_NAME_SEPARATOR) -> don't use current working directory - //avoid surprises with GlobalSettings.xml being newly created in each working directory - return getBinaryDir(); -#endif - else //use OS' standard paths - { - wxString userDirectory = wxStandardPathsBase::Get().GetUserDataDir(); - - if (!wxDirExists(userDirectory)) - ::wxMkdir(userDirectory); //only top directory needs to be created: no recursion necessary - - if (!endsWith(userDirectory, FILE_NAME_SEPARATOR)) - userDirectory += FILE_NAME_SEPARATOR; - - return userDirectory; - } -} - - -wxString zen::getLauncher() -{ -#ifdef FFS_WIN - return getInstallDir() + wxT("FreeFileSync.exe"); -#elif defined FFS_LINUX - return getBinaryDir() + wxT("FreeFileSync"); -#endif -} diff --git a/shared/standard_paths.h b/shared/standard_paths.h deleted file mode 100644 index 708a377d..00000000 --- a/shared/standard_paths.h +++ /dev/null @@ -1,26 +0,0 @@ -// ************************************************************************** -// * 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 STANDARDPATHS_H_INCLUDED -#define STANDARDPATHS_H_INCLUDED - -#include <wx/string.h> - - -namespace zen -{ -//------------------------------------------------------------------------------ -//global program directories -//------------------------------------------------------------------------------ -wxString getResourceDir(); //resource directory WITH path separator at end -wxString getConfigDir(); //config directory WITH path separator at end -//------------------------------------------------------------------------------ - -wxString getLauncher(); //full path to application launcher C:\...\FreeFileSync.exe -bool isPortableVersion(); -} - -#endif // STANDARDPATHS_H_INCLUDED diff --git a/shared/stl_tools.h b/shared/stl_tools.h deleted file mode 100644 index 6cfe35f8..00000000 --- a/shared/stl_tools.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************** -// * 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 STL_TOOLS_HEADER_84567184321434 -#define STL_TOOLS_HEADER_84567184321434 - -//no need to drag in any STL includes :) - -namespace zen -{ -template <class V, class Predicate> inline -void vector_remove_if(V& vec, Predicate p) -{ - vec.erase(std::remove_if(vec.begin(), vec.end(), p), vec.end()); -} - - -template <class S, class Predicate> inline -void set_remove_if(S& set, Predicate p) -{ - for (auto iter = set.begin(); iter != set.end();) - if (p(*iter)) - set.erase(iter++); - else - ++iter; -} - - -template <class M, class Predicate> inline -void map_remove_if(M& map, Predicate p) { set_remove_if(map, p); } - - -// binary search returning an iterator -template <class ForwardIterator, class T, typename Compare> inline -ForwardIterator custom_binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) -{ - first = std::lower_bound(first, last, value, comp); - if (first != last && !comp(value, *first)) - return first; - else - return last; -} -} - - -#endif //STL_TOOLS_HEADER_84567184321434
\ No newline at end of file diff --git a/shared/string_conv.h b/shared/string_conv.h deleted file mode 100644 index 976080fb..00000000 --- a/shared/string_conv.h +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************** -// * 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 STRINGCONV_H_INCLUDED -#define STRINGCONV_H_INCLUDED - -#include <string_utf8.h> -#include <wx/string.h> -#include "zstring.h" - -namespace zen -{ -inline wxString operator+(const wxString& lhs, const char* rhs) { return wxString(lhs) += utf8CvrtTo<wxString>(rhs); } -inline wxString operator+(const wxString& lhs, const Zstring& rhs) { return wxString(lhs) += utf8CvrtTo<wxString>(rhs); } - - -//conversion between Zstring and wxString -inline wxString toWx(const Zstring& str) { return utf8CvrtTo<wxString>(str); } -inline Zstring toZ(const wxString& str) { return utf8CvrtTo<Zstring>(str); } -} - -#endif // STRINGCONV_H_INCLUDED diff --git a/shared/string_tools.h b/shared/string_tools.h deleted file mode 100644 index 8951d942..00000000 --- a/shared/string_tools.h +++ /dev/null @@ -1,687 +0,0 @@ -// ************************************************************************** -// * This file is part of the zenXML project. It is distributed under the * -// * Boost Software License, Version 1.0. See accompanying file * -// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * -// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * -// ************************************************************************** - -#ifndef STRING_TOOLS_HEADER_213458973046 -#define STRING_TOOLS_HEADER_213458973046 - -#include <cstddef> //size_t -#include <cctype> //isspace -#include <cwctype> //iswspace -#include <cwchar> //swprintf -#include <cstdio> //sprintf -#include <algorithm> -#include <cassert> -#include <sstream> -#include <functional> -#include <vector> -#include "loki/TypeManip.h" -#include "loki/EmptyType.h" -#include "loki/TypeTraits.h" -#include "assert_static.h" -#ifdef _MSC_VER -template <> struct Loki::IsCustomUnsignedInt<unsigned __int64> { enum { value = 1 }; }; -template <> struct Loki::IsCustomSignedInt <signed __int64> { enum { value = 1 }; }; -#endif - - -//enhance arbitray string class with useful non-member functions: -namespace zen -{ -template <class C> size_t cStringLength(const C* str); //strlen() -template <class C> bool cStringIsWhiteSpace(C ch); -template <class C> bool cStringIsDigit(C ch); - -//uniform access to string-like types: classes and character arrays -/* -strBegin(): - std::wstring str(L"dummy"); - char array[] = "dummy"; - const wchar_t* iter = strBegin(str); //returns str.c_str() - const char* iter2 = strBegin(array); //returns array - -strLength(): - strLength(str); //equals str.size() - strLength(array); //equals cStringLength(array) - -StringTraits<>: - StringTraits<std::wstring>::CharType //equals wchar_t - StringTraits<wchar_t[5]> ::CharType //equals wchar_t - StringTraits<const wchar_t*>::isStringLike; //equals "true" - StringTraits<const int*> ::isStringLike; //equals "false" - StringTraits<std::wstring>::isStringClass //equals "true" - StringTraits<wchar_t[5]> ::isStringClass //equals "false" -*/ - -template <class S, class T> bool startsWith(const S& str, const T& prefix); //both S and T can be strings or char/wchar_t arrays or simple char/wchar_t -template <class S, class T> bool endsWith (const S& str, const T& postfix); // - -template <class S, class T> S afterLast (const S& str, const T& ch); //returns the whole string if ch not found -template <class S, class T> S beforeLast (const S& str, const T& ch); //returns empty string if ch not found -template <class S, class T> S afterFirst (const S& str, const T& ch); //returns empty string if ch not found -template <class S, class T> S beforeFirst(const S& str, const T& ch); //returns the whole string if ch not found - -template <class S, class T> std::vector<S> split(const S& str, const T& delimiter); -template <class S> void truncate(S& str, size_t newLen); -template <class S, class T, class U> void replace(S& str, const T& old, const U& replacement, bool replaceAll = true); -template <class S> void trim(S& str, bool fromLeft = true, bool fromRight = true); - -//high-performance conversion from numbers to strings -template <class S, class Num> S toString(const Num& number); -template <class Num, class S> Num toNumber(const S& str); - -//string to string conversion: converst string-like type into compatible target string class -template <class T, class S> T cvrtString(const S& str); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//---------------------- implementation ---------------------- - -template <class C> inline -size_t cStringLength(const C* str) //strlen() -{ - assert_static((Loki::IsSameType<C, char>::value || Loki::IsSameType<C, wchar_t>::value)); - size_t len = 0; - while (*str++ != 0) - ++len; - return len; -} - - -template <> inline -bool cStringIsWhiteSpace(char ch) -{ - //caveat 1: std::isspace() takes an int, but expects an unsigned char - //caveat 2: some parts of UTF-8 chars are erroneously seen as whitespace, e.g. the a0 from "\xec\x8b\xa0" (MSVC) - return static_cast<unsigned char>(ch) < 128 && - std::isspace(static_cast<unsigned char>(ch)) != 0; -} - -template <> inline bool cStringIsWhiteSpace(unsigned char ch) { return cStringIsWhiteSpace<char>(ch); } -template <> inline bool cStringIsWhiteSpace(signed char ch) { return cStringIsWhiteSpace<char>(ch); } -template <> inline bool cStringIsWhiteSpace(wchar_t ch) { return std::iswspace(ch) != 0; } - -template <> inline -bool cStringIsDigit(char ch) -{ - return std::isdigit(static_cast<unsigned char>(ch)) != 0; //caveat: takes an int, but expects an unsigned char -} - - -template <> -inline -bool cStringIsDigit(wchar_t ch) -{ - return std::iswdigit(ch) != 0; -} - -namespace implementation -{ -template <class T> -struct UnArray { typedef T NonArrayType; }; - -template <class T, int N> -struct UnArray<T[N]> { typedef T NonArrayType; }; - -template <class T> -struct UnPointer { typedef T NonPtrType; }; - -template <class T> -struct UnPointer<T*> { typedef T NonPtrType; }; - -template <class T> -struct UnReference { typedef T NonRefType; }; - -template <class T> -struct UnReference<T&> { typedef T NonRefType; }; - - -template<typename T> -class HasValueType -{ - typedef char Yes[1]; - typedef char No [2]; - - template <typename U> class HelperTp {}; - - //detect presence of a member type called value_type - template <class U> static Yes& hasMemberValueType(HelperTp<typename U::value_type>*); - template <class U> static No& hasMemberValueType(...); - -public: - enum { Result = sizeof(hasMemberValueType<T>(NULL)) == sizeof(Yes) - }; -}; - - -template<typename T, bool isClassType> -class HasStringMembers -{ -public: - enum { Result = false }; -}; - -template<typename T> -class HasStringMembers<T, true> -{ - typedef char Yes[1]; - typedef char No [2]; - - //detect presence of member functions (without specific restriction on return type, within T or one of it's base classes) - template <typename U, U t> class HelperFn {}; - - struct Fallback - { - int c_str; - int length; - }; - - template <class U> - struct Helper2 : public U, public Fallback {}; //U must be a class-type! - - //we don't know the exact declaration of the member attribute (may be in base class), but we know what NOT to expect: - template <class U> static No& hasMemberCstr(HelperFn<int Fallback::*, &Helper2<U>::c_str>*); - template <class U> static Yes& hasMemberCstr(...); - - template <class U> static No& hasMemberLength(HelperFn<int Fallback::*, &Helper2<U>::length>*); - template <class U> static Yes& hasMemberLength(...); -public: - enum { Result = sizeof(hasMemberCstr <T>(NULL)) == sizeof(Yes) && - sizeof(hasMemberLength<T>(NULL)) == sizeof(Yes) - }; -}; - -template <class S, bool isStringClass> struct StringTraits2 { typedef Loki::EmptyType Result; }; //"StringTraits2": fix some VS bug with namespace and partial template specialization - -template <class S> struct StringTraits2<S, true> { typedef typename S::value_type Result; }; -template <> struct StringTraits2<char, false> { typedef char Result; }; -template <> struct StringTraits2<wchar_t, false> { typedef wchar_t Result; }; -} - -template <class S> -struct StringTraits -{ -private: - typedef typename implementation::UnReference<S>::NonRefType NonRefType; - typedef typename Loki::TypeTraits<NonRefType>::NonConstType UndecoratedType; - - typedef typename implementation::UnArray<UndecoratedType>::NonArrayType NonArrayType; - typedef typename implementation::UnPointer<NonArrayType>::NonPtrType NonPtrType; - typedef typename Loki::TypeTraits<NonPtrType>::NonConstType NonConstValType; //handle "const char* const" -public: - enum - { - isStringClass = implementation::HasStringMembers<UndecoratedType, implementation::HasValueType<UndecoratedType>::Result>::Result - }; - - typedef typename implementation::StringTraits2<NonConstValType, isStringClass>::Result CharType; - - enum - { - isStringLike = Loki::IsSameType<CharType, char>::value || Loki::IsSameType<CharType, wchar_t>::value - }; -}; - - -template <class S> inline -const typename StringTraits<S>::CharType* strBegin(const S& str, typename S::value_type dummy = 0) { return str.c_str(); } //SFINAE: T must be a "string" - -template <class Char> -inline const typename StringTraits<Char>::CharType* strBegin(const Char* str) { return str; } -inline const char* strBegin(const char& ch) { return &ch; } -inline const wchar_t* strBegin(const wchar_t& ch) { return &ch; } - - -template <class S> inline -size_t strLength(const S& str, typename S::value_type dummy = 0) { return str.length(); } //SFINAE: T must be a "string" - -template <class Char> -inline size_t strLength(const Char* str) { return cStringLength(str); } -inline size_t strLength(char) { return 1; } -inline size_t strLength(wchar_t) { return 1; } - - -template <class S, class T> inline -bool startsWith(const S& str, const T& prefix) -{ - assert_static(StringTraits<S>::isStringLike); - assert_static(StringTraits<T>::isStringLike); - - const size_t pfLength = strLength(prefix); - if (strLength(str) < pfLength) - return false; - - return std::equal(strBegin(str), strBegin(str) + pfLength, - strBegin(prefix)); -} - - -template <class S, class T> inline -bool endsWith(const S& str, const T& postfix) -{ - assert_static(StringTraits<S>::isStringLike); - assert_static(StringTraits<T>::isStringLike); - - size_t strLen = strLength(str); - size_t pfLen = strLength(postfix); - if (strLen < pfLen) - return false; - - typedef typename StringTraits<S>::CharType CharType; - - const CharType* cmpBegin = strBegin(str) + strLen - pfLen; - return std::equal(cmpBegin, cmpBegin + pfLen, - strBegin(postfix)); -} - - -//returns the whole string if ch not found -template <class S, class T> inline -S afterLast(const S& str, const T& ch) -{ - assert_static(StringTraits<T>::isStringLike); - - const size_t pos = str.rfind(ch); - if (pos != S::npos) - { - size_t chLen = strLength(ch); - return S(str.c_str() + pos + chLen, str.length() - pos - chLen); - } - else - return str; -} - - -//returns empty string if ch not found -template <class S, class T> inline -S beforeLast(const S& str, const T& ch) -{ - assert_static(StringTraits<T>::isStringLike); - - const size_t pos = str.rfind(ch); - if (pos != S::npos) - return S(str.c_str(), pos); //data is non-empty string in this context: else ch would not have been found! - else - return S(); -} - - -//returns empty string if ch not found -template <class S, class T> inline -S afterFirst(const S& str, const T& ch) -{ - assert_static(StringTraits<T>::isStringLike); - - const size_t pos = str.find(ch); - if (pos != S::npos) - { - size_t chLen = strLength(ch); - return S(str.c_str() + pos + chLen, str.length() - pos - chLen); - } - else - return S(); - -} - - -//returns the whole string if ch not found -template <class S, class T> inline -S beforeFirst(const S& str, const T& ch) -{ - assert_static(StringTraits<T>::isStringLike); - - const size_t pos = str.find(ch); - if (pos != S::npos) - return S(str.c_str(), pos); //data is non-empty string in this context: else ch would not have been found! - else - return str; -} - - -template <class S, class T> inline -std::vector<S> split(const S& str, const T& delimiter) -{ - assert_static(StringTraits<T>::isStringLike); - - std::vector<S> output; - size_t bockStart = 0; - size_t delimLen = strLength(delimiter); - if (delimLen != 0) - { - for (size_t blockEnd = str.find(delimiter, bockStart); - blockEnd != S::npos; - bockStart = blockEnd + delimLen, blockEnd = str.find(delimiter, bockStart)) - { - output.push_back(S(str.c_str() + bockStart, blockEnd - bockStart)); - } - } - output.push_back(S(str.c_str() + bockStart, str.length() - bockStart)); - return output; -} - - -template <class S> inline -void truncate(S& str, size_t newLen) -{ - if (newLen < str.length()) - str.resize(newLen); -} - - -template <class S, class T, class U> inline -void replace(S& str, const T& old, const U& replacement, bool replaceAll) -{ - assert_static(StringTraits<T>::isStringLike); - assert_static(StringTraits<U>::isStringLike); - - size_t pos = 0; - size_t oldLen = strLength(old); - size_t repLen = strLength(replacement); - while ((pos = str.find(old, pos)) != S::npos) - { - str.replace(pos, oldLen, replacement); - pos += repLen; //move past the string that was replaced - - if (!replaceAll) - break; - } -} - - -template <class S> inline -void trim(S& str, bool fromLeft, bool fromRight) -{ - assert(fromLeft || fromRight); - - typedef typename S::value_type CharType; - - const CharType* newBegin = str.c_str(); - const CharType* newEnd = str.c_str() + str.length(); - - if (fromRight) - while (newBegin != newEnd && cStringIsWhiteSpace(newEnd[-1])) - --newEnd; - - if (fromLeft) - while (newBegin != newEnd && cStringIsWhiteSpace(*newBegin)) - ++newBegin; - - const size_t newLength = newEnd - newBegin; - if (newLength != str.length()) - { - if (newBegin != str.c_str()) - str = S(newBegin, newLength); //minor inefficiency: in case "str" is not shared, we could save an allocation and do a memory move only - else - str.resize(newLength); - } -} - - -namespace implementation -{ -template <class S, class T> -struct CnvtStringToString -{ - T convert(const S& src) const { return T(strBegin(src), strLength(src)); } -}; - -template <class S> -struct CnvtStringToString<S, S> //perf: we don't need a deep copy if string types match -{ - const S& convert(const S& src) const { return src; } -}; -} - -template <class T, class S> inline -T cvrtString(const S& str) { return implementation::CnvtStringToString<S, T>().convert(str); } - - -namespace implementation -{ -enum NumberType -{ - NUM_TYPE_SIGNED_INT, - NUM_TYPE_UNSIGNED_INT, - NUM_TYPE_FLOATING_POINT, - NUM_TYPE_OTHER, -}; - - -template <class S, class Num, NumberType> -struct CvrtNumberToString -{ - S convert(const Num& number) const //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20) - { - typedef typename StringTraits<S>::CharType CharType; - - std::basic_ostringstream<CharType> ss; - ss << number; - return cvrtString<S>(ss.str()); - } -}; - - -template <class S, class Num> -struct CvrtNumberToString<S, Num, NUM_TYPE_FLOATING_POINT> -{ - S convert(const Num& number) const { return convertFloat(number, typename StringTraits<S>::CharType()); } - -private: - S convertFloat(const Num& number, char) const - { - char buffer[50]; - int charsWritten = std::sprintf(buffer, "%f", static_cast<double>(number)); - return charsWritten > 0 ? S(buffer, charsWritten) : S(); - } - S convertFloat(const Num& number, wchar_t) const - { - wchar_t buffer[50]; -#ifdef __MINGW32__ - int charsWritten = ::swprintf(buffer, L"%f", static_cast<double>(number)); //MinGW does not comply to the C standard here -#else - int charsWritten = std::swprintf(buffer, 50, L"%f", static_cast<double>(number)); -#endif - return charsWritten > 0 ? S(buffer, charsWritten) : S(); - } -}; - -/* -perf: integer to string: (executed 10 mio. times) - std::stringstream - 14796 ms - std::sprintf - 3086 ms - hand coded - 778 ms -*/ - -template <class S, class Num> inline -S formatInteger(Num n, bool hasMinus) -{ - assert(n >= 0); - S output; - do - { - output += '0' + n % 10; - n /= 10; - } - while (n != 0); - if (hasMinus) - output += '-'; - - std::reverse(output.begin(), output.end()); - return output; -} - -template <class S, class Num> -struct CvrtNumberToString<S, Num, NUM_TYPE_SIGNED_INT> -{ - S convert(const Num& number) const { return formatInteger<S>(number < 0 ? -number : number, number < 0); } -}; - -template <class S, class Num> -struct CvrtNumberToString<S, Num, NUM_TYPE_UNSIGNED_INT> -{ - S convert(const Num& number) const { return formatInteger<S>(number, false); } -}; - -//-------------------------------------------------------------------------------- - -template <class S, class Num, NumberType> -struct CvrtStringToNumber -{ - Num convert(const S& str) const //default string to number conversion using streams: convenient, but SLOW - { - typedef typename StringTraits<S>::CharType CharType; - Num number = 0; - std::basic_istringstream<CharType>(cvrtString<std::basic_string<CharType> >(str)) >> number; - return number; - } -}; - - -template <class S, class Num> -struct CvrtStringToNumber<S, Num, NUM_TYPE_FLOATING_POINT> -{ - Num convert(const S& str) const { return convertFloat(strBegin(str)); } - -private: - Num convertFloat(const char* str) const { return std::strtod(str, NULL); } - Num convertFloat(const wchar_t* str) const { return std::wcstod(str, NULL); } -}; - -template <class Num, class S> -Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic -{ - typedef typename StringTraits<S>::CharType CharType; - - const CharType* first = strBegin(str); - const CharType* last = first + strLength(str); - - while (first != last && cStringIsWhiteSpace(*first)) //skip leading whitespace - ++first; - - hasMinusSign = false; //handle minus sign - if (first != last) - { - if (*first == '-') - { - hasMinusSign = true; - ++first; - } - else if (*first == '+') - ++first; - } - - Num number = 0; - for (const CharType* iter = first; iter != last; ++iter) - { - const CharType c = *iter; - if ('0' <= c && c <= '9') - { - number *= 10; - number += c - '0'; - } - else - { - assert(std::find_if(iter, last, std::not1(std::ptr_fun(&cStringIsWhiteSpace<CharType>))) == last); //rest of string should contain whitespace only - break; - } - } - return number; -} - - -template <class S, class Num> -struct CvrtStringToNumber<S, Num, NUM_TYPE_SIGNED_INT> -{ - Num convert(const S& str) const - { - bool hasMinusSign = false; //handle minus sign - const Num number = extractInteger<Num>(str, hasMinusSign); - return hasMinusSign ? -number : number; - } -}; - - -template <class S, class Num> -struct CvrtStringToNumber<S, Num, NUM_TYPE_UNSIGNED_INT> -{ - Num convert(const S& str) const //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic - { - bool hasMinusSign = false; //handle minus sign - const Num number = extractInteger<Num>(str, hasMinusSign); - if (hasMinusSign) - { - assert(false); - return 0U; - } - return number; - } -}; -} - - -template <class S, class Num> -inline -S toString(const Num& number) //convert number to string the C++ way -{ - using namespace implementation; - return CvrtNumberToString < S, Num, - Loki::TypeTraits<Num>::isSignedInt ? NUM_TYPE_SIGNED_INT : - Loki::TypeTraits<Num>::isUnsignedInt ? NUM_TYPE_UNSIGNED_INT : - Loki::TypeTraits<Num>::isFloat ? NUM_TYPE_FLOATING_POINT : - NUM_TYPE_OTHER - > ().convert(number); -} - - -template <class Num, class S> -inline -Num toNumber(const S& str) //convert string to number the C++ way -{ - using namespace implementation; - return CvrtStringToNumber < S, Num, - Loki::TypeTraits<Num>::isSignedInt ? NUM_TYPE_SIGNED_INT : - Loki::TypeTraits<Num>::isUnsignedInt ? NUM_TYPE_UNSIGNED_INT : - Loki::TypeTraits<Num>::isFloat ? NUM_TYPE_FLOATING_POINT : - NUM_TYPE_OTHER - > ().convert(str); -} - -} - -#endif //STRING_TOOLS_HEADER_213458973046 diff --git a/shared/string_utf8.h b/shared/string_utf8.h deleted file mode 100644 index 8c920752..00000000 --- a/shared/string_utf8.h +++ /dev/null @@ -1,335 +0,0 @@ -// ************************************************************************** -// * This file is part of the zenXML project. It is distributed under the * -// * Boost Software License, Version 1.0. See accompanying file * -// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * -// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * -// ************************************************************************** - -#ifndef STRING_UTF8_HEADER_01832479146991573473545 -#define STRING_UTF8_HEADER_01832479146991573473545 - -#include <iterator> -#include "loki/TypeManip.h" -#include "string_tools.h" -#include "assert_static.h" - -namespace zen -{ -//convert any(!) "string-like" object into target string by applying a UTF8 conversion (only if necessary!) -template <class TargetString, class SourceString> TargetString utf8CvrtTo(const SourceString& str); - -//convert wide to utf8 string; example: std::string tmp = toUtf8<std::string>(L"abc"); -template <class CharString, class WideString> -CharString wideToUtf8(const WideString& str); - -//convert utf8 string to wide; example: std::wstring tmp = utf8To<std::wstring>("abc"); -template <class WideString, class CharString> -WideString utf8ToWide(const CharString& str); - -const char BYTE_ORDER_MARK_UTF8[] = "\xEF\xBB\xBF"; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//----------------------- implementation ---------------------------------- -namespace implementation -{ -typedef unsigned int CodePoint; - -const CodePoint CODE_POINT_MAX = 0x10ffff; - -const CodePoint HIGH_SURROGATE = 0xd800; -const CodePoint HIGH_SURROGATE_MAX = 0xdbff; - -const CodePoint LOW_SURROGATE = 0xdc00; -const CodePoint LOW_SURROGATE_MAX = 0xdfff; - - -template <class OutputIterator> inline -OutputIterator codePointToUtf16(CodePoint cp, OutputIterator result) //http://en.wikipedia.org/wiki/UTF-16 -{ - typedef unsigned short Char16; //this isn't necessarily 16 bit, but all we need is an unsigned type - - assert(cp < HIGH_SURROGATE || LOW_SURROGATE_MAX < cp); //code points [0xd800, 0xdfff] are not allowed for UTF-16 - assert(cp <= CODE_POINT_MAX); - - if (cp < 0x10000) - *result++ = static_cast<Char16>(cp); - else - { - cp -= 0x10000; - *result++ = static_cast<Char16>((cp >> 10) + HIGH_SURROGATE); - *result++ = static_cast<Char16>((cp & 0x3ff) + LOW_SURROGATE); - } - return result; -} - - -template <class CharIterator, class Function> inline -Function utf16ToCodePoint(CharIterator first, CharIterator last, Function f) //f is a unary function taking a CodePoint as single parameter -{ - assert_static(sizeof(typename std::iterator_traits<CharIterator>::value_type) == 2); - typedef unsigned short Char16; //this isn't necessarily 16 bit, but all we need is an unsigned type - - for ( ; first != last; ++first) - { - CodePoint cp = static_cast<Char16>(*first); - if (HIGH_SURROGATE <= cp && cp <= HIGH_SURROGATE_MAX) - { - if (++first == last) - { - assert(false); //low surrogate expected - break; - } - assert(LOW_SURROGATE <= static_cast<Char16>(*first) && static_cast<Char16>(*first) <= LOW_SURROGATE_MAX); //low surrogate expected - cp = ((cp - HIGH_SURROGATE) << 10) + static_cast<Char16>(*first) - LOW_SURROGATE + 0x10000; - } - else - assert(cp < LOW_SURROGATE || LOW_SURROGATE_MAX < cp); //NO low surrogate expected - - f(cp); - } - return f; -} - - -template <class OutputIterator> inline -OutputIterator codePointToUtf8(CodePoint cp, OutputIterator result) //http://en.wikipedia.org/wiki/UTF-8 -{ - typedef unsigned char Char8; - - assert(cp <= CODE_POINT_MAX); - - if (cp < 0x80) - *result++ = static_cast<Char8>(cp); - else if (cp < 0x800) - { - *result++ = static_cast<Char8>((cp >> 6 ) | 0xc0); - *result++ = static_cast<Char8>((cp & 0x3f ) | 0x80); - } - else if (cp < 0x10000) - { - *result++ = static_cast<Char8>((cp >> 12 ) | 0xe0); - *result++ = static_cast<Char8>(((cp >> 6) & 0x3f ) | 0x80); - *result++ = static_cast<Char8>((cp & 0x3f ) | 0x80); - } - else - { - *result++ = static_cast<Char8>((cp >> 18 ) | 0xf0); - *result++ = static_cast<Char8>(((cp >> 12) & 0x3f ) | 0x80); - *result++ = static_cast<Char8>(((cp >> 6) & 0x3f ) | 0x80); - *result++ = static_cast<Char8>((cp & 0x3f ) | 0x80); - } - return result; -} - - -inline -size_t getUtf8Len(unsigned char ch) -{ - if (ch < 0x80) - return 1; - if (ch >> 5 == 0x6) - return 2; - if (ch >> 4 == 0xe) - return 3; - if (ch >> 3 == 0x1e) - return 4; - - assert(false); //no valid begin of UTF8 encoding - return 1; -} - - -template <class CharIterator, class Function> inline -Function utf8ToCodePoint(CharIterator first, CharIterator last, Function f) //f is a unary function taking a CodePoint as single parameter -{ - assert_static(sizeof(typename std::iterator_traits<CharIterator>::value_type) == 1); - typedef unsigned char Char8; - - for ( ; first != last; ++first) - { - auto getChar = [&](Char8 & ch) -> bool - { - if (++first == last) - { - assert(false); //low surrogate expected - return false; - } - ch = static_cast<Char8>(*first); - assert(ch >> 6 == 0x2); - return true; - }; - - CodePoint cp = static_cast<Char8>(*first); - switch (getUtf8Len(static_cast<Char8>(cp))) - { - case 1: - break; - case 2: - { - cp = (cp & 0x1f) << 6; - Char8 ch; - if (!getChar(ch)) continue; - cp += ch & 0x3f; - } - break; - case 3: - { - cp = (cp & 0xf) << 12; - Char8 ch; - if (!getChar(ch)) continue; - cp += (ch & 0x3f) << 6; - if (!getChar(ch)) continue; - cp += ch & 0x3f; - - } - break; - case 4: - { - cp = (cp & 0x7) << 18; - Char8 ch; - if (!getChar(ch)) continue; - cp += (ch & 0x3f) << 12; - if (!getChar(ch)) continue; - cp += (ch & 0x3f) << 6; - if (!getChar(ch)) continue; - cp += ch & 0x3f; - } - break; - default: - assert(false); - } - f(cp); - } - return f; -} - - -template <class String> -class AppendStringIterator: public std::iterator<std::output_iterator_tag, void, void, void, void> -{ -public: - explicit AppendStringIterator (String& x) : str(&x) {} - AppendStringIterator& operator= (typename String::value_type value) { *str += value; return *this; } - AppendStringIterator& operator* () { return *this; } - AppendStringIterator& operator++ () { return *this; } - AppendStringIterator operator++ (int) { return *this; } -private: - String* str; -}; - - -template <class WideString, class CharString> inline -WideString utf8ToWide(const CharString& str, Loki::Int2Type<2>) //windows: convert utf8 to utf16 wchar_t -{ - WideString output; - utf8ToCodePoint(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf16(cp, AppendStringIterator<WideString>(output)); }); - return output; -} - - -template <class WideString, class CharString> inline -WideString utf8ToWide(const CharString& str, Loki::Int2Type<4>) //other OS: convert utf8 to utf32 wchar_t -{ - WideString output; - utf8ToCodePoint(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { output += cp; }); - return output; -} - - -template <class CharString, class WideString> inline -CharString wideToUtf8(const WideString& str, Loki::Int2Type<2>) //windows: convert utf16-wchar_t to utf8 -{ - CharString output; - utf16ToCodePoint(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf8(cp, AppendStringIterator<CharString>(output)); }); - return output; -} - - -template <class CharString, class WideString> inline -CharString wideToUtf8(const WideString& str, Loki::Int2Type<4>) //other OS: convert utf32-wchar_t to utf8 -{ - CharString output; - std::for_each(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf8(cp, AppendStringIterator<CharString>(output)); }); - return output; -} -} - - -template <class WideString, class CharString> inline -WideString utf8ToWide(const CharString& str) -{ - assert_static((Loki::IsSameType<typename StringTraits<CharString>::CharType, char >::value)); - assert_static((Loki::IsSameType<typename StringTraits<WideString>::CharType, wchar_t>::value)); - - return implementation::utf8ToWide<WideString>(str, Loki::Int2Type<sizeof(wchar_t)>()); -} - - -template <class CharString, class WideString> inline -CharString wideToUtf8(const WideString& str) -{ - assert_static((Loki::IsSameType<typename StringTraits<CharString>::CharType, char >::value)); - assert_static((Loki::IsSameType<typename StringTraits<WideString>::CharType, wchar_t>::value)); - - return implementation::wideToUtf8<CharString>(str, Loki::Int2Type<sizeof(wchar_t)>()); -} - - -//------------------------------------------------------------------------------------------- -template <class TargetString, class SourceString> inline -TargetString utf8CvrtTo(const SourceString& str, char, wchar_t) { return utf8ToWide<TargetString>(str); } - -template <class TargetString, class SourceString> inline -TargetString utf8CvrtTo(const SourceString& str, wchar_t, char) { return wideToUtf8<TargetString>(str); } - -template <class TargetString, class SourceString> inline -TargetString utf8CvrtTo(const SourceString& str, char, char) { return cvrtString<TargetString>(str); } - -template <class TargetString, class SourceString> inline -TargetString utf8CvrtTo(const SourceString& str, wchar_t, wchar_t) { return cvrtString<TargetString>(str); } - -template <class TargetString, class SourceString> inline -TargetString utf8CvrtTo(const SourceString& str) -{ - return utf8CvrtTo<TargetString>(str, typename StringTraits<SourceString>::CharType(), - typename StringTraits<TargetString>::CharType()); -} -} - -#endif //STRING_UTF8_HEADER_01832479146991573473545 diff --git a/shared/symlink_target.h b/shared/symlink_target.h deleted file mode 100644 index 9ab0ea3f..00000000 --- a/shared/symlink_target.h +++ /dev/null @@ -1,145 +0,0 @@ -// ************************************************************************** -// * 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 SYMLINK_WIN_H_INCLUDED -#define SYMLINK_WIN_H_INCLUDED - -#include "loki/ScopeGuard.h" -#include "last_error.h" -#include "file_error.h" -#include "i18n.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#include "WinIoCtl.h" -#include "privilege.h" -#include "long_path_prefix.h" - -#elif defined FFS_LINUX -#include <unistd.h> -#endif - - -#ifdef _MSC_VER //I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structures and cross fingers... - -//from ntifs.h -typedef struct _REPARSE_DATA_BUFFER -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) -#endif - -namespace -{ -//retrieve raw target data of symlink or junction -Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw FileError -{ - using namespace zen; -#ifdef FFS_WIN - //FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx - - try //reading certain symlinks requires admin rights! This shall not cause an error in user mode! - { - //allow access to certain symbolic links/junctions - Privileges::getInstance().ensureActive(SE_BACKUP_NAME); //throw FileError - } - catch (...) {} - - const HANDLE hLink = ::CreateFile(applyLongPathPrefix(linkPath).c_str(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - if (hLink == INVALID_HANDLE_VALUE) - throw FileError(_("Error resolving symbolic link:") + "\n\"" + linkPath + "\"" + "\n\n" + getLastErrorFormatted()); - LOKI_ON_BLOCK_EXIT2(::CloseHandle(hLink)); - - //respect alignment issues... - const DWORD bufferSize = REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE; - std::vector<char> buffer(bufferSize); - - DWORD bytesReturned; //dummy value required by FSCTL_GET_REPARSE_POINT! - if (!::DeviceIoControl(hLink, //__in HANDLE hDevice, - FSCTL_GET_REPARSE_POINT, //__in DWORD dwIoControlCode, - NULL, //__in_opt LPVOID lpInBuffer, - 0, //__in DWORD nInBufferSize, - &buffer[0], //__out_opt LPVOID lpOutBuffer, - bufferSize, //__in DWORD nOutBufferSize, - &bytesReturned, //__out_opt LPDWORD lpBytesReturned, - NULL)) //__inout_opt LPOVERLAPPED lpOverlapped - throw FileError(_("Error resolving symbolic link:") + "\n\"" + linkPath + "\"" + "\n\n" + getLastErrorFormatted()); - - REPARSE_DATA_BUFFER& reparseData = *reinterpret_cast<REPARSE_DATA_BUFFER*>(&buffer[0]); //REPARSE_DATA_BUFFER needs to be artificially enlarged! - - Zstring output; - if (reparseData.ReparseTag == IO_REPARSE_TAG_SYMLINK) - { - output = Zstring(reparseData.SymbolicLinkReparseBuffer.PathBuffer + reparseData.SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), - reparseData.SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - } - else if (reparseData.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) - { - output = Zstring(reparseData.MountPointReparseBuffer.PathBuffer + reparseData.MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), - reparseData.MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - } - else - throw FileError(_("Error resolving symbolic link:") + "\n\"" + linkPath + "\"" + "\n\n" + "Not a symbolic link or junction!"); - - //absolute symlinks and junctions technically start with \??\ while relative ones do not - if (output.StartsWith(Zstr("\\??\\"))) - output = Zstring(output.c_str() + 4, output.length() - 4); - - return output; - -#elif defined FFS_LINUX - const int BUFFER_SIZE = 10000; - std::vector<char> buffer(BUFFER_SIZE); - - const int bytesWritten = ::readlink(linkPath.c_str(), &buffer[0], BUFFER_SIZE); - if (bytesWritten < 0 || bytesWritten >= BUFFER_SIZE) - { - std::wstring errorMessage = _("Error resolving symbolic link:") + "\n\"" + linkPath + "\""; - if (bytesWritten < 0) - errorMessage += L"\n\n" + getLastErrorFormatted(); - throw FileError(errorMessage); - } - buffer[bytesWritten] = 0; //set null-terminating char - - return Zstring(&buffer[0], bytesWritten); -#endif -} -} - -#endif // SYMLINK_WIN_H_INCLUDED diff --git a/shared/taskbar.cpp b/shared/taskbar.cpp deleted file mode 100644 index 9edc7288..00000000 --- a/shared/taskbar.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// ************************************************************************** -// * 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 "taskbar.h" - -#ifdef FFS_WIN -#include "Taskbar_Seven/taskbar.h" -#include "dll_loader.h" -#include "build_info.h" -#include "assert_static.h" -#include <wx/msw/wrapwin.h> //includes "windows.h" - -#elif defined HAVE_UBUNTU_UNITY -#include <unity/unity/unity.h> -#endif - -using namespace util; - - -#ifdef FFS_WIN -using namespace tbseven; - -namespace -{ -bool windows7TaskbarAvailable() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if (::GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 6 || - (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1); //task bar progress available with Windows 7 - //XP has majorVersion == 5, minorVersion == 1 - //Server 2003 has majorVersion == 5, minorVersion == 2 - //Seven has majorVersion == 6, minorVersion == 1 - //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} -} -//######################################################################################################## - - -class Taskbar::Pimpl //throw (TaskbarNotAvailable) -{ -public: - Pimpl(const wxTopLevelWindow& window) : - assocWindow(window.GetHWND()), - setStatus_ (getDllName(), setStatusFctName), - setProgress_(getDllName(), setProgressFctName) - { - if (!assocWindow || !setProgress_ || !setStatus_) - throw TaskbarNotAvailable(); - - if (!windows7TaskbarAvailable()) - throw TaskbarNotAvailable(); - } - - ~Pimpl() { setStatus(STATUS_NOPROGRESS); } - - void setStatus(Status status) - { - TaskBarStatus tbSevenStatus = tbseven::STATUS_NORMAL; - switch (status) - { - case Taskbar::STATUS_NOPROGRESS: - tbSevenStatus = tbseven::STATUS_NOPROGRESS; - break; - case Taskbar::STATUS_INDETERMINATE: - tbSevenStatus = tbseven::STATUS_INDETERMINATE; - break; - case Taskbar::STATUS_NORMAL: - tbSevenStatus = tbseven::STATUS_NORMAL; - break; - case Taskbar::STATUS_ERROR: - tbSevenStatus = tbseven::STATUS_ERROR; - break; - case Taskbar::STATUS_PAUSED: - tbSevenStatus = tbseven::STATUS_PAUSED; - break; - } - - setStatus_(assocWindow, tbSevenStatus); - } - - void setProgress(double fraction) - { - setProgress_(assocWindow, fraction * 100000, 100000); - } - -private: - void* assocWindow; //HWND - const util::DllFun<SetStatusFct> setStatus_; - const util::DllFun<SetProgressFct> setProgress_; -}; - -#elif defined HAVE_UBUNTU_UNITY //Ubuntu unity -namespace -{ -const char FFS_DESKTOP_FILE[] = "freefilesync.desktop"; -} - -class Taskbar::Pimpl //throw (TaskbarNotAvailable) -{ -public: - Pimpl(const wxTopLevelWindow& window) : - tbEntry(unity_launcher_entry_get_for_desktop_id(FFS_DESKTOP_FILE)) - //tbEntry(unity_launcher_entry_get_for_app_uri("application://freefilesync.desktop")) - { - if (!tbEntry) - throw TaskbarNotAvailable(); - } - - ~Pimpl() { setStatus(STATUS_NOPROGRESS); } //it seems UnityLauncherEntry* does not need destruction - - void setStatus(Status status) - { - switch (status) - { - case Taskbar::STATUS_ERROR: - unity_launcher_entry_set_urgent(tbEntry, true); - break; - - case Taskbar::STATUS_NOPROGRESS: - case Taskbar::STATUS_INDETERMINATE: - unity_launcher_entry_set_urgent(tbEntry, false); - unity_launcher_entry_set_progress_visible(tbEntry, false); - break; - - case Taskbar::STATUS_NORMAL: - unity_launcher_entry_set_urgent(tbEntry, false); - unity_launcher_entry_set_progress_visible(tbEntry, true); - break; - - case Taskbar::STATUS_PAUSED: - unity_launcher_entry_set_urgent (tbEntry, false); - break; - } - } - - void setProgress(double fraction) - { - unity_launcher_entry_set_progress(tbEntry, fraction); - } - -private: - UnityLauncherEntry* tbEntry; -}; - - -#else //no taskbar support yet -class Taskbar::Pimpl -{ -public: - Pimpl(const wxTopLevelWindow& window) { throw TaskbarNotAvailable(); } - void setStatus(Status status) {} - void setProgress(size_t current, size_t total) {} - -}; -#endif - - -//######################################################################################################## -Taskbar::Taskbar(const wxTopLevelWindow& window) : pimpl_(new Pimpl(window)) {} //throw TaskbarNotAvailable -Taskbar::~Taskbar() {} //std::unique_ptr ... - -void Taskbar::setStatus(Status status) { pimpl_->setStatus(status); } -void Taskbar::setProgress(double fraction) { pimpl_->setProgress(fraction); } diff --git a/shared/taskbar.h b/shared/taskbar.h deleted file mode 100644 index b78b4494..00000000 --- a/shared/taskbar.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************** -// * 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 TASKBARPROGRESS_H_INCLUDED -#define TASKBARPROGRESS_H_INCLUDED - -#include <wx/toplevel.h> -#include <memory> - -/* -Windows 7; show progress in windows superbar via ITaskbarList3 Interface (http://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx) - -Ubuntu: use Unity interface (optional) - -Define HAVE_UBUNTU_UNITY and set: - Compiler flag: `pkg-config --cflags unity` - Linker flag: `pkg-config --libs unity` -*/ - -namespace util -{ -class TaskbarNotAvailable {}; - -class Taskbar -{ -public: - Taskbar(const wxTopLevelWindow& window); //throw TaskbarNotAvailable() - ~Taskbar(); - - enum Status - { - STATUS_NOPROGRESS, - STATUS_INDETERMINATE, - STATUS_NORMAL, - STATUS_ERROR, - STATUS_PAUSED - }; - - void setStatus(Status status); - void setProgress(double fraction); //between [0, 1] - -private: - class Pimpl; - std::unique_ptr<Pimpl> pimpl_; -}; - -} - -#endif // TASKBARPROGRESS_H_INCLUDED diff --git a/shared/toggle_button.cpp b/shared/toggle_button.cpp deleted file mode 100644 index 24f74bc7..00000000 --- a/shared/toggle_button.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************** -// * 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 "toggle_button.h" - -void ToggleButton::init(const wxBitmap& activeBmp, - const wxString& activeTooltip, - const wxBitmap& inactiveBmp, - const wxString& inactiveTooltip) -{ - m_activeBmp = activeBmp; - m_activeTooltip = activeTooltip; - m_inactiveBmp = inactiveBmp; - m_inactiveTooltip = inactiveTooltip; - - //load resources - setActive(active); -} - - -bool ToggleButton::isActive() const -{ - return active; -} - - -void ToggleButton::toggle() -{ - setActive(!active); -} - - -void ToggleButton::setActive(bool value) -{ - active = value; - - if (active) - { - SetBitmapLabel(m_activeBmp); - SetToolTip(m_activeTooltip); - } - else - { - SetBitmapLabel(m_inactiveBmp); - SetToolTip(m_inactiveTooltip); - } -} diff --git a/shared/toggle_button.h b/shared/toggle_button.h deleted file mode 100644 index f333ca24..00000000 --- a/shared/toggle_button.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************** -// * 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 TOGGLEBUTTON_H_INCLUDED -#define TOGGLEBUTTON_H_INCLUDED - -#include <wx/bmpbuttn.h> - -class ToggleButton : public wxBitmapButton -{ -public: - ToggleButton(wxWindow* parent, - wxWindowID id, - const wxBitmap& bitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxButtonNameStr) : - wxBitmapButton(parent, id, bitmap, pos, size, style, validator, name), - active(false) - { - SetLayoutDirection(wxLayout_LeftToRight); //avoid mirroring RTL languages like Hebrew or Arabic - } - - void init(const wxBitmap& activeBmp, - const wxString& activeTooltip, - const wxBitmap& inactiveBmp, - const wxString& inactiveTooltip); - - void setActive(bool value); - bool isActive() const; - void toggle(); - -private: - bool active; - - wxBitmap m_activeBmp; - wxString m_activeTooltip; - - wxBitmap m_inactiveBmp; - wxString m_inactiveTooltip; -}; - - -#endif // TOGGLEBUTTON_H_INCLUDED diff --git a/shared/util.cpp b/shared/util.cpp deleted file mode 100644 index 292d87c1..00000000 --- a/shared/util.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// ************************************************************************** -// * 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 "util.h" -#include "zstring.h" -#include "i18n.h" -#include "last_error.h" -#include "global_func.h" - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#endif - - -wxString zen::extractJobName(const wxString& configFilename) -{ - const wxString shortName = configFilename.AfterLast(FILE_NAME_SEPARATOR); //returns the whole string if seperator not found - const wxString jobName = shortName.BeforeLast(wxChar('.')); //returns empty string if seperator not found - return jobName.IsEmpty() ? shortName : jobName; -} - - -wxString zen::formatFilesizeToShortString(UInt64 size) -{ - if (to<Int64>(size) < 0) return _("Error"); - - if (size <= 999U) - { - wxString output = _P("1 Byte", "%x Bytes", to<int>(size)); - output.Replace(wxT("%x"), toStringSep(size)); //no decimal places in case of bytes - return output; - } - else - { - double filesize = to<double>(size); - - filesize /= 1024; - wxString output = _("%x KB"); - if (filesize > 999) - { - filesize /= 1024; - output = _("%x MB"); - if (filesize > 999) - { - filesize /= 1024; - output = _("%x GB"); - if (filesize > 999) - { - filesize /= 1024; - output = _("%x TB"); - if (filesize > 999) - { - filesize /= 1024; - output = _("%x PB"); - } - } - } - } - //print just three significant digits: 0,01 | 0,11 | 1,11 | 11,1 | 111 - const size_t leadDigitCount = common::getDigitCount(static_cast<size_t>(filesize)); //number of digits before decimal point - if (leadDigitCount == 0 || leadDigitCount > 3) - return _("Error"); - - output.Replace(wxT("%x"), wxString::Format(wxT("%.*f"), static_cast<int>(3 - leadDigitCount), filesize)); - return output; - } -} - - -wxString zen::formatPercentage(double fraction) -{ - wxString output = _("%x%"); - output.Replace(wxT("%x"), wxString::Format(wxT("%3.2f"), fraction * 100.0), false); - return output; -} - - -wxString ffs_Impl::includeNumberSeparator(const wxString& number) -{ - wxString output(number); - for (size_t i = output.size(); i > 3; i -= 3) - output.insert(i - 3, zen::getThousandsSeparator()); - - return output; -} - - -void zen::scrollToBottom(wxScrolledWindow* scrWindow) -{ - int height = 0; - scrWindow->GetClientSize(NULL, &height); - - int pixelPerLine = 0; - scrWindow->GetScrollPixelsPerUnit(NULL, &pixelPerLine); - - if (height > 0 && pixelPerLine > 0) - { - const int scrollLinesTotal = scrWindow->GetScrollLines(wxVERTICAL); - const int scrollLinesOnScreen = height / pixelPerLine; - const int scrollPosBottom = scrollLinesTotal - scrollLinesOnScreen; - - if (0 <= scrollPosBottom) - scrWindow->Scroll(0, scrollPosBottom); - } -} - - -namespace -{ -#ifdef FFS_WIN -bool isVistaOrLater() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - //symbolic links are supported starting with Vista - if (::GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5; //XP has majorVersion == 5, minorVersion == 1; Vista majorVersion == 6, dwMinorVersion == 0 - //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} -#endif -} - - -wxString zen::utcTimeToLocalString(zen::Int64 utcTime) -{ -#ifdef FFS_WIN - FILETIME lastWriteTimeUtc = tofiletime(utcTime); //convert ansi C time to FILETIME - - SYSTEMTIME systemTimeLocal = {}; - - static const bool useNewLocalTimeCalculation = isVistaOrLater(); - if (useNewLocalTimeCalculation) //use DST setting from source date (like in Windows 7, see http://msdn.microsoft.com/en-us/library/ms724277(VS.85).aspx) - { - SYSTEMTIME systemTimeUtc = {}; - if (!::FileTimeToSystemTime( - &lastWriteTimeUtc, //__in const FILETIME *lpFileTime, - &systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime - return _("Error"); - - if (!::SystemTimeToTzSpecificLocalTime( - NULL, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone, - &systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime, - &systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime - return _("Error"); - } - else //use DST setting (like in Windows 2000 and XP) - { - FILETIME fileTimeLocal = {}; - if (!::FileTimeToLocalFileTime( //convert to local time - &lastWriteTimeUtc, //pointer to UTC file time to convert - &fileTimeLocal)) //pointer to converted file time - return _("Error"); - - if (!::FileTimeToSystemTime(&fileTimeLocal, //pointer to file time to convert - &systemTimeLocal)) //pointer to structure to receive system time - return _("Error"); - } - - const wxDateTime localTime(systemTimeLocal.wDay, - wxDateTime::Month(systemTimeLocal.wMonth - 1), - systemTimeLocal.wYear, - systemTimeLocal.wHour, - systemTimeLocal.wMinute, - systemTimeLocal.wSecond); - -#elif defined FFS_LINUX - const time_t fileTime = to<time_t>(utcTime); - const tm* timeinfo = ::localtime(&fileTime); //convert to local time - - /* - char buffer[50]; - ::strftime(buffer, 50, "%Y-%m-%d %H:%M:%S", timeinfo); - return zToWx(buffer); - */ - const wxDateTime localTime(timeinfo->tm_mday, - wxDateTime::Month(timeinfo->tm_mon), - 1900 + timeinfo->tm_year, - timeinfo->tm_hour, - timeinfo->tm_min, - timeinfo->tm_sec); -#endif - - return localTime.FormatDate() + wxT(" ") + localTime.FormatTime(); -} diff --git a/shared/util.h b/shared/util.h deleted file mode 100644 index e45262ab..00000000 --- a/shared/util.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************** -// * 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 UTIL_H_INCLUDED -#define UTIL_H_INCLUDED - -#include <wx/string.h> -#include <wx/scrolwin.h> -#include "string_tools.h" -#include "int64.h" - -namespace zen -{ -wxString extractJobName(const wxString& configFilename); - -wxString formatFilesizeToShortString(UInt64 filesize); -wxString formatPercentage(double fraction); //between [0, 1] - -template <class NumberType> -wxString toStringSep(NumberType number); //convert number to wxString including thousands separator - -void scrollToBottom(wxScrolledWindow* scrWindow); - -wxString utcTimeToLocalString(Int64 utcTime); //throw std::runtime_error -} - - - - - - - - - - - - - - - - - - - - - - - - - - -//--------------- inline impelementation ------------------------------------------- - -//helper function! not to be used directly -namespace ffs_Impl -{ -wxString includeNumberSeparator(const wxString& number); -} - - -namespace zen -{ -template <class NumberType> inline -wxString toStringSep(NumberType number) -{ - return ffs_Impl::includeNumberSeparator(zen::toString<wxString>(number)); -} -} - - -#endif // UTIL_H_INCLUDED diff --git a/shared/warn_static.h b/shared/warn_static.h deleted file mode 100644 index 66513871..00000000 --- a/shared/warn_static.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************** -// * This file is part of the zenXML project. It is distributed under the * -// * Boost Software License, Version 1.0. See accompanying file * -// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * -// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * -// ************************************************************************** - -#ifndef WARN_STATIC_HEADER_08724567834560832745 -#define WARN_STATIC_HEADER_08724567834560832745 - -/* -Portable Compile-Time Warning ------------------------------ -Usage: - warn_static("my message") -*/ - -#ifdef _MSC_VER -#define MAKE_STRING_SUB(NUM) #NUM -#define MAKE_STRING(NUM) MAKE_STRING_SUB(NUM) - -#define warn_static(TXT) \ - __pragma(message (__FILE__ "(" MAKE_STRING(__LINE__) "): Warning: " ## TXT)) - -#elif defined __GNUC__ -#define LOKI_CONCAT( X, Y ) LOKI_CONCAT_SUB( X, Y ) -#define LOKI_CONCAT_SUB( X, Y ) X##Y - -#define warn_static(TXT) \ - typedef int STATIC_WARNING __attribute__ ((deprecated)); \ - enum { LOKI_CONCAT(warn_static_dummy_value, __LINE__) = sizeof(STATIC_WARNING) }; -#endif - - -#endif //WARN_STATIC_HEADER_08724567834560832745
\ No newline at end of file diff --git a/shared/wx_choice_enum.h b/shared/wx_choice_enum.h deleted file mode 100644 index b8833725..00000000 --- a/shared/wx_choice_enum.h +++ /dev/null @@ -1,129 +0,0 @@ -// ************************************************************************** -// * 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 WX_CHOICE_ENUM_H_INCLUDED -#define WX_CHOICE_ENUM_H_INCLUDED - -#include <wx/choice.h> -#include <vector> - -//handle mapping of enum values to wxChoice controls - -/* -Example: - -Member variable: - zen::EnumDescrList<EnumOnError> enumDescrMap; - -Constructor code: - enumDescrMap. - add(ON_ERROR_POPUP , _("Show pop-up") , _("Show pop-up on errors or warnings")). - add(ON_ERROR_IGNORE, _("Ignore errors") , _("Hide all error and warning messages")). - add(ON_ERROR_EXIT , _("Exit instantly"), _("Abort synchronization immediately")); - -Set enum value: - setEnumVal(enumDescrMap, *m_choiceHandleError, value); - -Get enum value: - value = getEnumVal(enumDescrMap, *m_choiceHandleError) - -Update enum tooltips (after user changed selection): - updateTooltipEnumVal(enumDescrMap, *m_choiceHandleError); -*/ - - -namespace zen -{ -template <class Enum> -struct EnumDescrList -{ - EnumDescrList& add(Enum value, const wxString& text, const wxString& tooltip = wxEmptyString) - { - descrList.push_back(std::make_pair(value, std::make_pair(text, tooltip))); - return *this; - } - typedef std::vector<std::pair<Enum, std::pair<wxString, wxString> > > DescrList; - DescrList descrList; -}; -template <class Enum> void setEnumVal(const EnumDescrList<Enum>& mapping, wxChoice& ctrl, Enum value); -template <class Enum> Enum getEnumVal(const EnumDescrList<Enum>& mapping, const wxChoice& ctrl); -template <class Enum> void updateTooltipEnumVal(const EnumDescrList<Enum>& mapping, wxChoice& ctrl); - - - - - - - - - - - - - - - - - - - - - - - - - - - -//--------------- inline impelementation ------------------------------------------- -template <class Enum> -void setEnumVal(const EnumDescrList<Enum>& mapping, wxChoice& ctrl, Enum value) -{ - ctrl.Clear(); - - int selectedPos = 0; - for (typename EnumDescrList<Enum>::DescrList::const_iterator i = mapping.descrList.begin(); i != mapping.descrList.end(); ++i) - { - ctrl.Append(i->second.first); - if (i->first == value) - { - selectedPos = i - mapping.descrList.begin(); - - if (!i->second.second.empty()) - ctrl.SetToolTip(i->second.second); - } - } - - ctrl.SetSelection(selectedPos); -} - -template <class Enum> -Enum getEnumVal(const EnumDescrList<Enum>& mapping, const wxChoice& ctrl) -{ - const int selectedPos = ctrl.GetSelection(); - - if (0 <= selectedPos && selectedPos < static_cast<int>(mapping.descrList.size())) - return mapping.descrList[selectedPos].first; - else - { - assert(false); - return Enum(0); - } -} - -template <class Enum> void updateTooltipEnumVal(const EnumDescrList<Enum>& mapping, wxChoice& ctrl) -{ - const Enum value = getEnumVal(mapping, ctrl); - - for (typename EnumDescrList<Enum>::DescrList::const_iterator i = mapping.descrList.begin(); i != mapping.descrList.end(); ++i) - if (i->first == value) - ctrl.SetToolTip(i->second.second); -} - -} - - -#endif //WX_CHOICE_ENUM_H_INCLUDED diff --git a/shared/wx_timespan.h b/shared/wx_timespan.h deleted file mode 100644 index d11b328e..00000000 --- a/shared/wx_timespan.h +++ /dev/null @@ -1,166 +0,0 @@ -// ************************************************************************** -// * 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 WX_TIMESPAN_CTRL_HEADER_INCLUDED -#define WX_TIMESPAN_CTRL_HEADER_INCLUDED - -#include <wx/textctrl.h> -#include <wx/datetime.h> -#include <wx/spinbutt.h> -#include <wx/sizer.h> - -//user friendly time span control -//- constructor is compatible with a wxTextControl -//- emits change event: wxEVT_TIMESPAN_CHANGE - -namespace zen -{ -inline -wxEventType getEventType() //external linkage -{ - static wxEventType evt = wxNewEventType(); - return evt; -} -const wxEventType wxEVT_TIMESPAN_CHANGE = getEventType(); - - -class TimeSpanCtrl : public wxPanel -{ -public: - TimeSpanCtrl(wxWindow* parent, wxWindowID id, - const wxString& value = wxEmptyString, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxTextCtrlNameStr) : - wxPanel(parent, id, pos, size, style, name), - FORMAT_TIMESPAN(wxT("%H:%M:%S")) - { - wxBoxSizer* bSizer27 = new wxBoxSizer( wxHORIZONTAL ); - - m_textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE ); - bSizer27->Add(m_textCtrl, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); - - m_spinBtn = new wxSpinButton(this, wxID_ANY, wxDefaultPosition, wxSize( 20, -1 ), wxSP_ARROW_KEYS ); - bSizer27->Add(m_spinBtn, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); - - SetSizer(bSizer27); - Layout(); - - //connect events - m_spinBtn ->Connect(wxEVT_SCROLL_LINEUP, wxEventHandler (TimeSpanCtrl::OnSpinUp), NULL, this); - m_spinBtn ->Connect(wxEVT_SCROLL_LINEDOWN, wxEventHandler (TimeSpanCtrl::OnSpinDown), NULL, this); - m_textCtrl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (TimeSpanCtrl::OnKeyPress), NULL, this); - m_textCtrl->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(TimeSpanCtrl::OnMouseAction), NULL, this); - - setValue(0); - } - - void setValue(int span) //unit: [s] - { - wxString newValue; - if (span < 0) - { - newValue += wxT("- "); - span = -span; - } - newValue += wxTimeSpan::Seconds(span).Format(FORMAT_TIMESPAN); - - long pos = m_textCtrl->GetInsertionPoint(); - pos += newValue.size() - m_textCtrl->GetValue().size(); - - m_textCtrl->ChangeValue(newValue); - m_textCtrl->SetInsertionPoint(pos); - - wxCommandEvent chgEvent(wxEVT_TIMESPAN_CHANGE); - wxPostEvent(this, chgEvent); - } - - int getValue() const - { - wxString textVal = m_textCtrl->GetValue(); - textVal.Trim(false); - - bool isNegative = false; - if (textVal.StartsWith(wxT("-"))) - { - isNegative = true; - textVal = textVal.substr(1); - } - textVal.Trim(false); - - wxDateTime tmp(time_t(0)); - if (tmp.ParseFormat(textVal, FORMAT_TIMESPAN, wxDateTime(tmp)) == NULL) - return 0; - - return (isNegative ? -1 : 1) * - (tmp.GetHour () * 3600 + - tmp.GetMinute() * 60 + - tmp.GetSecond()); - } - -private: - void OnSpinUp (wxEvent& event) { spinValue(true); } - void OnSpinDown(wxEvent& event) { spinValue(false); } - - void OnKeyPress(wxKeyEvent& event) - { - const int keyCode = event.GetKeyCode(); - switch (keyCode) - { - case WXK_UP: - case WXK_NUMPAD_UP: - return spinValue(true); - case WXK_DOWN: - case WXK_NUMPAD_DOWN: - return spinValue(false); - default: - event.Skip(); - } - } - - void OnMouseAction(wxMouseEvent& event) - { - int delta = event.GetWheelRotation(); - if (delta > 0) - spinValue(true); - else if (delta < 0) - spinValue(false); - else - event.Skip(); - } - - void spinValue(bool up) - { - wxString textval = m_textCtrl->GetValue(); - long pos = m_textCtrl->GetInsertionPoint(); - - int stepSize = 1; - if (pos <= static_cast<long>(textval.size())) - { - int delimCount = std::count(textval.begin() + pos, textval.end(), wxT(':')); - if (delimCount == 1) - stepSize = 60; //minute - else if (delimCount == 2) - stepSize = 3600; //hour - } - - if (!up) - stepSize *= -1; - - setValue(getValue() + stepSize); - } - - wxTextCtrl* m_textCtrl; - wxSpinButton* m_spinBtn; - - const wxString FORMAT_TIMESPAN; -}; -} - - -#endif //WX_TIMESPAN_CTRL_HEADER_INCLUDED diff --git a/shared/xml_base.cpp b/shared/xml_base.cpp deleted file mode 100644 index e0b497f9..00000000 --- a/shared/xml_base.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// ************************************************************************** -// * 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 "xml_base.h" -#include <file_handling.h> -#include <string_conv.h> -#include <file_io.h> -#include <i18n.h> - -using namespace zen; - - -//loadXmlDocument vs loadStream: -//1. better error reporting -//2. quick exit if (potentially large) input file is not an XML -void xmlAccess::loadXmlDocument(const wxString& filename, XmlDoc& doc) //throw FfsXmlError -{ - std::string stream; - try - { - { - //quick test whether input is an XML: avoid loading large binary files up front! - const std::string xmlBegin = "<?xml version="; - std::vector<char> buffer(xmlBegin.size() + sizeof(zen::BYTE_ORDER_MARK_UTF8)); - - FileInput inputFile(toZ(filename)); //throw FileError; - const size_t bytesRead = inputFile.read(&buffer[0], buffer.size()); //throw FileError - - const std::string fileBegin(&buffer[0], bytesRead); - - if (!startsWith(fileBegin, xmlBegin) && - !startsWith(fileBegin, zen::BYTE_ORDER_MARK_UTF8 + xmlBegin)) //respect BOM! - throw FfsXmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + filename + wxT("\"")); - } - - const zen::UInt64 fs = zen::getFilesize(toZ(filename)); //throw FileError - stream.resize(to<size_t>(fs)); - - FileInput inputFile(toZ(filename)); //throw FileError - const size_t bytesRead = inputFile.read(&stream[0], stream.size()); //throw FileError - if (bytesRead < to<size_t>(fs)) - { - wxString errorMessage = wxString(_("Error reading file:")) + wxT("\n\"") + filename + wxT("\""); - throw FfsXmlError(errorMessage + wxT("\n\n")); - } - } - catch (const FileError& error) //more detailed error messages than with wxWidgets - { - throw FfsXmlError(error.msg()); - } - - try - { - zen::parse(stream, doc); //throw XmlParsingError - } - catch (const XmlParsingError&) - { - throw FfsXmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + filename + wxT("\"")); - } -} - - -const wxString xmlAccess::getErrorMessageFormatted(const XmlIn& in) -{ - wxString errorMessage = wxString(_("Could not read values for the following XML nodes:")) + wxT("\n"); - - std::vector<wxString> failedNodes = in.getErrorsAs<wxString>(); - std::for_each(failedNodes.begin(), failedNodes.end(), - [&](const wxString& str) { errorMessage += str + wxT('\n'); }); - - return errorMessage; -} - - -void xmlAccess::saveXmlDocument(const zen::XmlDoc& doc, const wxString& filename) //throw (FfsXmlError) -{ - std::string stream = serialize(doc); //throw () - - bool saveNecessary = true; - try - { - if (zen::getFilesize(toZ(filename)) == stream.size()) //throw FileError - try - { - if (zen::loadStream(filename) == stream) //throw XmlFileError - saveNecessary = false; - } - catch (const zen::XmlFileError&) {} - } - catch (FileError&) {} - - if (saveNecessary) - try - { - FileOutput outputFile(toZ(filename), FileOutput::ACC_OVERWRITE); //throw FileError - outputFile.write(stream.c_str(), stream.length()); // - } - catch (const FileError& error) //more detailed error messages than with wxWidgets - { - throw FfsXmlError(error.msg()); - } -} diff --git a/shared/xml_base.h b/shared/xml_base.h deleted file mode 100644 index 37d79863..00000000 --- a/shared/xml_base.h +++ /dev/null @@ -1,21 +0,0 @@ -// ************************************************************************** -// * 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 XMLBASE_H_INCLUDED -#define XMLBASE_H_INCLUDED - -#include <xml_error.h> -#include <zenXml/zenxml.h> - -namespace xmlAccess -{ -void saveXmlDocument(const zen::XmlDoc& doc, const wxString& filename); //throw (FfsXmlError) -void loadXmlDocument(const wxString& filename, zen::XmlDoc& doc); //throw FfsXmlError() - -const wxString getErrorMessageFormatted(const zen::XmlIn& in); -} - -#endif // XMLBASE_H_INCLUDED diff --git a/shared/xml_error.h b/shared/xml_error.h deleted file mode 100644 index 6e17670a..00000000 --- a/shared/xml_error.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************** -// * 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 XMLERROR_H_INCLUDED -#define XMLERROR_H_INCLUDED - -#include <wx/string.h> - - -namespace xmlAccess -{ - -class FfsXmlError //Exception class -{ -public: - enum Severity - { - WARNING = 77, - FATAL - }; - - FfsXmlError(const wxString& message, Severity sev = FATAL) : errorMessage(message), m_severity(sev) {} - - const wxString& msg() const { return errorMessage; } - Severity getSeverity() const { return m_severity; } -private: - const wxString errorMessage; - const Severity m_severity; -}; -} - -#endif // XMLERROR_H_INCLUDED diff --git a/shared/zbase.h b/shared/zbase.h deleted file mode 100644 index 5f404887..00000000 --- a/shared/zbase.h +++ /dev/null @@ -1,903 +0,0 @@ -// ************************************************************************** -// * 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 Z_BASE_H_INCLUDED -#define Z_BASE_H_INCLUDED - -#include <cassert> -#include <vector> -#include <sstream> -#include <algorithm> -#include <string_tools.h> -#include <boost/detail/atomic_count.hpp> - -/* -Allocator Policy: ------------------ - void* allocate(size_t size) //throw (std::bad_alloc) - void deallocate(void* ptr) - size_t calcCapacity(size_t length) -*/ -class AllocatorOptimalSpeed //exponential growth + min size -{ -public: - //::operator new/ ::operator delete show same performance characterisics like malloc()/free()! - static void* allocate(size_t size) { return ::operator new(size); } //throw (std::bad_alloc) - static void deallocate(void* ptr) { ::operator delete(ptr); } - static size_t calcCapacity(size_t length) { return std::max<size_t>(16, length + length / 2); } -}; - - -class AllocatorOptimalMemory //no wasted memory, but more reallocations required when manipulating string -{ -public: - static void* allocate(size_t size) { return ::operator new(size); } //throw (std::bad_alloc) - static void deallocate(void* ptr) { ::operator delete(ptr); } - static size_t calcCapacity(size_t length) { return length; } -}; - -/* -Storage Policy: ---------------- -template <typename T, //Character Type - class AP> //Allocator Policy - - T* create(size_t size) - T* create(size_t size, size_t minCapacity) - T* clone(T* ptr) - void destroy(T* ptr) - bool canWrite(const T* ptr, size_t minCapacity) //needs to be checked before writing to "ptr" - size_t length(const T* ptr) - void setLength(T* ptr, size_t newLength) -*/ - -template < typename T, //Character Type - class AP > //Allocator Policy -class StorageDeepCopy : public AP -{ -protected: - ~StorageDeepCopy() {} - - static T* create(size_t size) { return create(size, size); } - static T* create(size_t size, size_t minCapacity) - { - const size_t newCapacity = AP::calcCapacity(minCapacity); - assert(newCapacity >= minCapacity); - assert(minCapacity >= size); - - Descriptor* const newDescr = static_cast<Descriptor*>(AP::allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(T))); - - newDescr->length = size; - newDescr->capacity = newCapacity; - - return reinterpret_cast<T*>(newDescr + 1); - } - - static T* clone(T* ptr) - { - T* newData = create(length(ptr)); - std::copy(ptr, ptr + length(ptr) + 1, newData); - return newData; - } - - static void destroy(T* ptr) { AP::deallocate(descr(ptr)); } - - //this needs to be checked before writing to "ptr" - static bool canWrite(const T* ptr, size_t minCapacity) { return minCapacity <= descr(ptr)->capacity; } - static size_t length(const T* ptr) { return descr(ptr)->length; } - - static void setLength(T* ptr, size_t newLength) - { - assert(canWrite(ptr, newLength)); - descr(ptr)->length = newLength; - } - -private: - struct Descriptor - { - size_t length; - size_t capacity; //allocated size without null-termination - }; - - static Descriptor* descr( T* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } - static const Descriptor* descr(const T* ptr) { return reinterpret_cast<const Descriptor*>(ptr) - 1; } -}; - - -template < typename T, //Character Type - class AP > //Allocator Policy -class StorageRefCountThreadSafe : public AP -{ -protected: - ~StorageRefCountThreadSafe() {} - - static T* create(size_t size) - { - return create(size, size); - } - - static T* create(size_t size, size_t minCapacity) - { - const size_t newCapacity = AP::calcCapacity(minCapacity); - assert(newCapacity >= minCapacity); - assert(minCapacity >= size); - - Descriptor* const newDescr = static_cast<Descriptor*>(AP::allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(T))); - new (newDescr) Descriptor(1, size, newCapacity); - - return reinterpret_cast<T*>(newDescr + 1); - } - - static T* clone(T* ptr) - { - assert(descr(ptr)->refCount > 0); - ++descr(ptr)->refCount; - return ptr; - } - - static void destroy(T* ptr) - { - if (--descr(ptr)->refCount == 0) - { - descr(ptr)->~Descriptor(); - AP::deallocate(descr(ptr)); - } - } - - static bool canWrite(const T* ptr, size_t minCapacity) //needs to be checked before writing to "ptr" - { - assert(descr(ptr)->refCount > 0); - return descr(ptr)->refCount == 1 && minCapacity <= descr(ptr)->capacity; - } - - static size_t length(const T* ptr) - { - return descr(ptr)->length; - } - - static void setLength(T* ptr, size_t newLength) - { - assert(canWrite(ptr, newLength)); - descr(ptr)->length = newLength; - } - -private: - struct Descriptor - { - Descriptor(long rc, size_t len, size_t cap) : refCount(rc), length(len), capacity(cap) {} - - boost::detail::atomic_count refCount; //practically no perf loss: ~0.2%! (FFS comparison) - size_t length; - size_t capacity; //allocated size without null-termination - }; - - static Descriptor* descr( T* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } - static const Descriptor* descr(const T* ptr) { return reinterpret_cast<const Descriptor*>(ptr) - 1; } -}; - - -//perf note: interstingly StorageDeepCopy and StorageRefCountThreadSafe show same performance in FFS comparison - -template < class T, //Character Type - template <class, class> class SP = StorageRefCountThreadSafe, //Storage Policy - class AP = AllocatorOptimalSpeed > //Allocator Policy -class Zbase : public SP<T, AP> -{ -public: - Zbase(); - Zbase(const T* source); //implicit conversion from a C-string - Zbase(const T* source, size_t length); - Zbase(const Zbase& source); - Zbase(Zbase && tmp); - explicit Zbase(T source); //dangerous if implicit: T buffer[]; Zbase name = buffer; ups... - //allow explicit construction from different string type, prevent ambiguity via SFINAE - template <class S> explicit Zbase(const S& other, typename S::value_type = 0); - ~Zbase(); - - //operator const T* () const; //NO implicit conversion to a C-string!! Many problems... one of them: if we forget to provide operator overloads, it'll just work with a T*... - - //STL accessors - typedef T* iterator; - typedef const T* const_iterator; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - const T* begin() const; - const T* end() const; - T* begin(); - T* end(); - - //wxString-like functions - bool StartsWith(const Zbase& prefix ) const { return zen::startsWith(*this, prefix ); } - bool StartsWith(const T* prefix ) const { return zen::startsWith(*this, prefix ); } - bool StartsWith( T prefix ) const { return zen::startsWith(*this, prefix ); } - bool EndsWith (const Zbase& postfix) const { return zen::endsWith (*this, postfix); } - bool EndsWith (const T* postfix) const { return zen::endsWith (*this, postfix); } - bool EndsWith ( T postfix) const { return zen::endsWith (*this, postfix); } - void Truncate(size_t newLen) { return zen::truncate(*this, newLen); } - Zbase& Replace(const Zbase& old, const Zbase& replacement, bool replaceAll = true) { zen::replace(*this, old, replacement, replaceAll); return *this; } - Zbase AfterLast( T ch) const { return zen::afterLast (*this, ch); } //returns the whole string if "ch" not found - Zbase BeforeLast( T ch) const { return zen::beforeLast (*this, ch); } //returns empty string if "ch" not found - Zbase AfterFirst( T ch) const { return zen::afterFirst (*this, ch); } //returns empty string if "ch" not found - Zbase BeforeFirst(T ch) const { return zen::beforeFirst(*this, ch); } //returns the whole string if "ch" not found - void Trim(bool fromLeft = true, bool fromRight = true) { zen::trim(*this, fromLeft, fromRight); } - std::vector<Zbase> Split(T delimiter) const { return zen::split(*this, delimiter); } - std::vector<Zbase> Split(const Zbase& delimiter) const { return zen::split(*this, delimiter); } - - //number conversion - template <class N> static Zbase fromNumber(N number) { return zen::toString<Zbase>(number); } - template <class N> N toNumber() const { return zen::toNumber<N>(*this); } - - //std::string functions - size_t length() const; - size_t size() const; - const T* c_str() const; //C-string format with NULL-termination - const T* data() const; //internal representation, NULL-termination not guaranteed - const T operator[](size_t pos) const; - Zbase substr(size_t pos = 0, size_t len = npos) const; - bool empty() const; - void clear(); - size_t find(const Zbase& str, size_t pos = 0) const; // - size_t find(const T* str, size_t pos = 0) const; //returns "npos" if not found - size_t find(T ch, size_t pos = 0) const; // - size_t rfind(T ch, size_t pos = npos) const; // - size_t rfind(const T* str, size_t pos = npos) const; // - Zbase& replace(size_t pos1, size_t n1, const Zbase& str); - void reserve(size_t minCapacity); - Zbase& assign(const T* source, size_t len); - void resize(size_t newSize, T fillChar = 0); - void swap(Zbase& other); - void push_back(T val); //STL access - - Zbase& operator=(const Zbase& source); - Zbase& operator=(Zbase && tmp); - Zbase& operator=(const T* source); - Zbase& operator=(T source); - Zbase& operator+=(const Zbase& other); - Zbase& operator+=(const T* other); - Zbase& operator+=(T ch); - - static const size_t npos = static_cast<size_t>(-1); - -private: - Zbase(int); //detect usage errors - Zbase& operator=(int); // - - T* rawStr; -}; - -template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs); -template <class T, template <class, class> class SP, class AP> bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs); - -template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs); -template <class T, template <class, class> class SP, class AP> bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs); - -template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const T* rhs); -template <class T, template <class, class> class SP, class AP> bool operator< (const T* lhs, const Zbase<T, SP, AP>& rhs); - -template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs); -template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+( T lhs, const Zbase<T, SP, AP>& rhs); -template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//################################# inline implementation ######################################## -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase() -{ - //resist the temptation to avoid this allocation by referening a static global: NO performance advantage, MT issues! - rawStr = this->create(0); - rawStr[0] = 0; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase(T source) -{ - rawStr = this->create(1); - rawStr[0] = source; - rawStr[1] = 0; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase(const T* source) -{ - const size_t sourceLen = zen::cStringLength(source); - rawStr = this->create(sourceLen); - std::copy(source, source + sourceLen + 1, rawStr); //include null-termination -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase(const T* source, size_t sourceLen) -{ - rawStr = this->create(sourceLen); - std::copy(source, source + sourceLen, rawStr); - rawStr[sourceLen] = 0; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase(const Zbase<T, SP, AP>& source) -{ - rawStr = this->clone(source.rawStr); -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::Zbase(Zbase<T, SP, AP> && tmp) -{ - rawStr = this->clone(tmp.rawStr); //for a ref-counting string there probably isn't a faster way, even with r-value references -} - - -template <class T, template <class, class> class SP, class AP> -template <class S> -inline -Zbase<T, SP, AP>::Zbase(const S& other, typename S::value_type) -{ - const size_t sourceLen = other.size(); - rawStr = this->create(sourceLen); - std::copy(other.c_str(), other.c_str() + sourceLen, rawStr); - rawStr[sourceLen] = 0; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>::~Zbase() -{ - this->destroy(rawStr); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::find(const Zbase& str, size_t pos) const -{ - assert(pos <= length()); - const T* thisEnd = end(); //respect embedded 0 - const T* iter = std::search(begin() + pos, thisEnd, - str.begin(), str.end()); - return iter == thisEnd ? npos : iter - begin(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::find(const T* str, size_t pos) const -{ - assert(pos <= length()); - const T* thisEnd = end(); //respect embedded 0 - const T* iter = std::search(begin() + pos, thisEnd, - str, str + zen::cStringLength(str)); - return iter == thisEnd ? npos : iter - begin(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::find(T ch, size_t pos) const -{ - assert(pos <= length()); - const T* thisEnd = end(); - const T* iter = std::find(begin() + pos, thisEnd, ch); //respect embedded 0 - return iter == thisEnd ? npos : iter - begin(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::rfind(T ch, size_t pos) const -{ - assert(pos == npos || pos <= length()); - - const size_t thisLen = length(); - if (thisLen == 0) return npos; - pos = std::min(thisLen - 1, pos); //handle "npos" and "pos == length()" implicitly - - while (rawStr[pos] != ch) //pos points to last char of the string - { - if (pos == 0) - return npos; - --pos; - } - return pos; -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::rfind(const T* str, size_t pos) const -{ - assert(pos == npos || pos <= length()); - - const size_t strLen = zen::cStringLength(str); - const T* currEnd = pos == npos ? end() : begin() + std::min(pos + strLen, length()); - - const T* iter = std::find_end(begin(), currEnd, - str, str + strLen); - return iter == currEnd ? npos : iter - begin(); -} - - -template <class T, template <class, class> class SP, class AP> -Zbase<T, SP, AP>& Zbase<T, SP, AP>::replace(size_t pos1, size_t n1, const Zbase& str) -{ - assert(str.data() < rawStr || rawStr + length() < str.data()); //str mustn't point to data in this string - assert(pos1 + n1 <= length()); - - const size_t n2 = str.length(); - - const size_t oldLen = length(); - if (oldLen == 0) - return *this = str; - - const size_t newLen = oldLen - n1 + n2; - - if (canWrite(rawStr, newLen)) - { - if (n1 < n2) //move remainder right -> std::copy_backward - { - std::copy_backward(rawStr + pos1 + n1, rawStr + oldLen + 1, rawStr + newLen + 1); //include null-termination - setLength(rawStr, newLen); - } - else if (n1 > n2) //shift left -> std::copy - { - std::copy(rawStr + pos1 + n1, rawStr + oldLen + 1, rawStr + pos1 + n2); //include null-termination - setLength(rawStr, newLen); - } - - std::copy(str.data(), str.data() + n2, rawStr + pos1); - } - else - { - //copy directly into new string - T* const newStr = this->create(newLen); - - std::copy(rawStr, rawStr + pos1, newStr); - std::copy(str.data(), str.data() + n2, newStr + pos1); - std::copy(rawStr + pos1 + n1, rawStr + oldLen + 1, newStr + pos1 + n2); //include null-termination - - destroy(rawStr); - rawStr = newStr; - } - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -void Zbase<T, SP, AP>::resize(size_t newSize, T fillChar) -{ - if (canWrite(rawStr, newSize)) - { - if (length() < newSize) - std::fill(rawStr + length(), rawStr + newSize, fillChar); - rawStr[newSize] = 0; - setLength(rawStr, newSize); //keep after call to length() - } - else - { - T* newStr = this->create(newSize); - newStr[newSize] = 0; - - if (length() < newSize) - { - std::copy(rawStr, rawStr + length(), newStr); - std::fill(newStr + length(), newStr + newSize, fillChar); - } - else - std::copy(rawStr, rawStr + newSize, newStr); - - destroy(rawStr); - rawStr = newStr; - } -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator==(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) -{ - return lhs.length() == rhs.length() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); //respect embedded 0 -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs) -{ - return lhs.length() == zen::cStringLength(rhs) && std::equal(lhs.begin(), lhs.end(), rhs); //respect embedded 0 -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs) -{ - return operator==(rhs, lhs); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator!=(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator<(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) -{ - return std::lexicographical_compare(lhs.begin(), lhs.end(), //respect embedded 0 - rhs.begin(), rhs.end()); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator<(const Zbase<T, SP, AP>& lhs, const T* rhs) -{ - return std::lexicographical_compare(lhs.begin(), lhs.end(), //respect embedded 0 - rhs, rhs + zen::cStringLength(rhs)); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool operator<(const T* lhs, const Zbase<T, SP, AP>& rhs) -{ - return std::lexicographical_compare(lhs, lhs + zen::cStringLength(lhs), //respect embedded 0 - rhs.begin(), rhs.end()); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::length() const -{ - return SP<T, AP>::length(rawStr); -} - - -template <class T, template <class, class> class SP, class AP> -inline -size_t Zbase<T, SP, AP>::size() const -{ - return length(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -const T* Zbase<T, SP, AP>::c_str() const -{ - return rawStr; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const T* Zbase<T, SP, AP>::data() const -{ - return rawStr; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const T Zbase<T, SP, AP>::operator[](size_t pos) const -{ - assert(pos < length()); - return rawStr[pos]; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const T* Zbase<T, SP, AP>::begin() const -{ - return rawStr; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const T* Zbase<T, SP, AP>::end() const -{ - return rawStr + length(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -T* Zbase<T, SP, AP>::begin() -{ - reserve(length()); - return rawStr; -} - - -template <class T, template <class, class> class SP, class AP> -inline -T* Zbase<T, SP, AP>::end() -{ - return begin() + length(); -} - - -template <class T, template <class, class> class SP, class AP> -inline -void Zbase<T, SP, AP>::push_back(T val) -{ - operator+=(val); -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool Zbase<T, SP, AP>::empty() const -{ - return length() == 0; -} - - -template <class T, template <class, class> class SP, class AP> -inline -void Zbase<T, SP, AP>::clear() -{ - if (!empty()) - { - if (canWrite(rawStr, 0)) - { - rawStr[0] = 0; //keep allocated memory - setLength(rawStr, 0); // - } - else - *this = Zbase(); - } -} - - -template <class T, template <class, class> class SP, class AP> -inline -const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) -{ - return Zbase<T, SP, AP>(lhs) += rhs; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs) -{ - return Zbase<T, SP, AP>(lhs) += rhs; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs) -{ - return Zbase<T, SP, AP>(lhs) += rhs; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const Zbase<T, SP, AP> operator+(T lhs, const Zbase<T, SP, AP>& rhs) -{ - return (Zbase<T, SP, AP>() += lhs) += rhs; -} - - -template <class T, template <class, class> class SP, class AP> -inline -const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs) -{ - return Zbase<T, SP, AP>(lhs) += rhs; -} - - -template <class T, template <class, class> class SP, class AP> -inline -void Zbase<T, SP, AP>::swap(Zbase<T, SP, AP>& other) -{ - std::swap(rawStr, other.rawStr); -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP> Zbase<T, SP, AP>::substr(size_t pos, size_t len) const -{ - assert(pos + (len == npos ? 0 : len) <= length()); - return Zbase(rawStr + pos, len == npos ? length() - pos : len); -} - - -template <class T, template <class, class> class SP, class AP> -inline -void Zbase<T, SP, AP>::reserve(size_t minCapacity) //make unshared and check capacity -{ - if (!canWrite(rawStr, minCapacity)) - { - //allocate a new string - T* newStr = create(length(), std::max(minCapacity, length())); //reserve() must NEVER shrink the string: logical const! - std::copy(rawStr, rawStr + length() + 1, newStr); //include NULL-termination - - destroy(rawStr); - rawStr = newStr; - } -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::assign(const T* source, size_t len) -{ - if (canWrite(rawStr, len)) - { - std::copy(source, source + len, rawStr); - rawStr[len] = 0; //include null-termination - setLength(rawStr, len); - } - else - *this = Zbase(source, len); - - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(const Zbase<T, SP, AP>& source) -{ - Zbase(source).swap(*this); - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(Zbase<T, SP, AP> && tmp) -{ - swap(tmp); - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(const T* source) -{ - return assign(source, zen::cStringLength(source)); -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(T source) -{ - if (canWrite(rawStr, 1)) - { - rawStr[0] = source; - rawStr[1] = 0; //include null-termination - setLength(rawStr, 1); - } - else - *this = Zbase(source); - - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(const Zbase<T, SP, AP>& other) -{ - const size_t thisLen = length(); - const size_t otherLen = other.length(); - reserve(thisLen + otherLen); //make unshared and check capacity - - std::copy(other.rawStr, other.rawStr + otherLen + 1, rawStr + thisLen); //include null-termination - setLength(rawStr, thisLen + otherLen); - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(const T* other) -{ - const size_t thisLen = length(); - const size_t otherLen = zen::cStringLength(other); - reserve(thisLen + otherLen); //make unshared and check capacity - - std::copy(other, other + otherLen + 1, rawStr + thisLen); //include null-termination - setLength(rawStr, thisLen + otherLen); - return *this; -} - - -template <class T, template <class, class> class SP, class AP> -inline -Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(T ch) -{ - const size_t thisLen = length(); - reserve(thisLen + 1); //make unshared and check capacity - rawStr[thisLen] = ch; - rawStr[thisLen + 1] = 0; - setLength(rawStr, thisLen + 1); - return *this; -} - -#endif //Z_BASE_H_INCLUDED diff --git a/shared/zstring.cpp b/shared/zstring.cpp deleted file mode 100644 index 45762000..00000000 --- a/shared/zstring.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// ************************************************************************** -// * 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 "zstring.h" -#include <stdexcept> -#include <boost/thread/once.hpp> - -#ifdef FFS_WIN -#include <wx/msw/wrapwin.h> //includes "windows.h" -#undef min -#undef max -#include "dll_loader.h" -#endif //FFS_WIN - -#ifndef NDEBUG -#include <wx/string.h> -#include <iostream> -#include <cstdlib> -#endif - - -#ifndef NDEBUG -LeakChecker::~LeakChecker() -{ - if (activeStrings.size() > 0) - { - int rowCount = 0; - std::string leakingStrings; - - for (VoidPtrSizeMap::const_iterator i = activeStrings.begin(); - i != activeStrings.end() && ++rowCount <= 20; - ++i) - leakingStrings += "\"" + rawMemToString(i->first, i->second) + "\"\n"; - - const std::string message = std::string("Memory leak detected!") + "\n\n" - + "Candidates:\n" + leakingStrings; -#ifdef FFS_WIN - MessageBoxA(NULL, message.c_str(), "Error", 0); -#else - std::cerr << message; - std::abort(); -#endif - } -} - - -LeakChecker& LeakChecker::instance() -{ - static LeakChecker inst; - return inst; -} - -//caveat: function scope static initialization is not thread-safe in VS 2010! => make sure to call at app start! -namespace -{ -struct Dummy { Dummy() { LeakChecker::instance(); }} blah; -} - - -std::string LeakChecker::rawMemToString(const void* ptr, size_t size) -{ - std::string output = std::string(reinterpret_cast<const char*>(ptr), size); - output.erase(std::remove(output.begin(), output.end(), 0), output.end()); //remove intermediate 0-termination - if (output.size() > 100) - output.resize(100); - return output; -} - - -void LeakChecker::reportProblem(const std::string& message) //throw (std::logic_error) -{ -#ifdef FFS_WIN - ::MessageBoxA(NULL, message.c_str(), "Error", 0); -#else - std::cerr << message; -#endif - throw std::logic_error("Memory leak! " + message); -} -#endif //NDEBUG - - -#ifdef FFS_WIN -namespace -{ -bool hasInvariantLocale() -{ - OSVERSIONINFO osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - //invariant locale has been introduced with XP - if (GetVersionEx(&osvi)) - return osvi.dwMajorVersion > 5 || - (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1); //XP has majorVersion == 5, minorVersion == 1 - //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx - return false; -} - -#ifndef LOCALE_INVARIANT -#define LOCALE_INVARIANT 0x007f -#endif - - -//warning: LOCALE_INVARIANT is NOT available with Windows 2000, so we have to make yet another distinction... -const LCID ZSTRING_INVARIANT_LOCALE = hasInvariantLocale() ? - LOCALE_INVARIANT : - MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); //see: http://msdn.microsoft.com/en-us/goglobal/bb688122.aspx - - -//try to call "CompareStringOrdinal" for low-level string comparison: unfortunately available not before Windows Vista! -//by a factor ~3 faster than old string comparison using "LCMapString" -typedef int (WINAPI* CompareStringOrdinalFunc)(LPCWSTR lpString1, - int cchCount1, - LPCWSTR lpString2, - int cchCount2, - BOOL bIgnoreCase); -util::DllFun<CompareStringOrdinalFunc> ordinalCompare; //caveat: function scope static initialization is not thread-safe in VS 2010! -boost::once_flag initCmpStrOrdOnce = BOOST_ONCE_INIT; -} - - -int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB) -{ - boost::call_once(initCmpStrOrdOnce, []() { ordinalCompare = util::DllFun<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal"); }); - - if (ordinalCompare) //this additional test has no noticeable performance impact - { - const int rv = ordinalCompare(a, //pointer to first string - static_cast<int>(sizeA), //size, in bytes or characters, of first string - b, //pointer to second string - static_cast<int>(sizeB), //size, in bytes or characters, of second string - true); //ignore case - if (rv == 0) - throw std::runtime_error("Error comparing strings (ordinal)!"); - else - return rv - 2; //convert to C-style string compare result - } - 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": - - const size_t minSize = std::min(sizeA, sizeB); - - if (minSize == 0) //LCMapString does not allow input sizes of 0! - return static_cast<int>(sizeA) - static_cast<int>(sizeB); - - int rv = 0; //always initialize... - if (minSize <= 5000) //performance optimization: stack - { - wchar_t bufferA[5000]; - 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) - throw std::runtime_error("Error comparing strings! (LCMapString)"); - - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, b, static_cast<int>(minSize), bufferB, 5000) == 0) - throw std::runtime_error("Error comparing strings! (LCMapString)"); - - rv = ::wmemcmp(bufferA, bufferB, minSize); - } - else //use freestore - { - std::vector<wchar_t> bufferA(minSize); - std::vector<wchar_t> bufferB(minSize); - - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, a, static_cast<int>(minSize), &bufferA[0], static_cast<int>(minSize)) == 0) - throw std::runtime_error("Error comparing strings! (LCMapString: FS)"); - - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, b, static_cast<int>(minSize), &bufferB[0], static_cast<int>(minSize)) == 0) - throw std::runtime_error("Error comparing strings! (LCMapString: FS)"); - - rv = ::wmemcmp(&bufferA[0], &bufferB[0], minSize); - } - - return rv == 0 ? - static_cast<int>(sizeA) - static_cast<int>(sizeB) : - 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 -} - - -void z_impl::makeUpperCaseWin(wchar_t* str, size_t size) -{ - if (size == 0) //LCMapString does not allow input sizes of 0! - return; - - //use Windows' upper case conversion: faster than ::CharUpper() - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, str, static_cast<int>(size), str, static_cast<int>(size)) == 0) - throw std::runtime_error("Error converting to upper case! (LCMapString)"); -} - - -/* -#include <fstream> - extern std::wofstream statShared; -extern std::wofstream statLowCapacity; -extern std::wofstream statOverwrite; - -std::wstring p(ptr); -p.erase(std::remove(p.begin(), p.end(), L'\n'), p.end()); -p.erase(std::remove(p.begin(), p.end(), L','), p.end()); - - if (descr(ptr)->refCount > 1) - statShared << - minCapacity << L"," << - descr(ptr)->refCount << L"," << - descr(ptr)->length << L"," << - descr(ptr)->capacity << L"," << - p << L"\n"; -else if (minCapacity > descr(ptr)->capacity) - statLowCapacity << - minCapacity << L"," << - descr(ptr)->refCount << L"," << - descr(ptr)->length << L"," << - descr(ptr)->capacity << L"," << - p << L"\n"; -else - statOverwrite << - minCapacity << L"," << - descr(ptr)->refCount << L"," << - descr(ptr)->length << L"," << - descr(ptr)->capacity << L"," << - p << L"\n"; -*/ - -#endif //FFS_WIN diff --git a/shared/zstring.h b/shared/zstring.h deleted file mode 100644 index 8c30007b..00000000 --- a/shared/zstring.h +++ /dev/null @@ -1,216 +0,0 @@ -// ************************************************************************** -// * 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 ZSTRING_H_INCLUDED -#define ZSTRING_H_INCLUDED - -#include "zbase.h" -#include <cstring> //strcmp() - -#ifndef NDEBUG -#include "boost_thread_wrap.h" //include <boost/thread.hpp> -#include <map> -#endif - - -#ifndef NDEBUG -class LeakChecker //small test for memory leaks -{ -public: - void insert(const void* ptr, size_t size) - { - boost::lock_guard<boost::mutex> dummy(lockActStrings); - if (activeStrings.find(ptr) != activeStrings.end()) - reportProblem(std::string("Fatal Error: New memory points into occupied space: ") + rawMemToString(ptr, size)); - - activeStrings[ptr] = size; - } - - void remove(const void* ptr) - { - boost::lock_guard<boost::mutex> dummy(lockActStrings); - if (activeStrings.find(ptr) == activeStrings.end()) - reportProblem(std::string("Fatal Error: No memory available for deallocation at this location!")); - - activeStrings.erase(ptr); - } - - static LeakChecker& instance(); - -private: - LeakChecker() {} - LeakChecker(const LeakChecker&); - LeakChecker& operator=(const LeakChecker&); - ~LeakChecker(); - - static std::string rawMemToString(const void* ptr, size_t size); - void reportProblem(const std::string& message); //throw (std::logic_error) - - boost::mutex lockActStrings; - typedef std::map<const void*, size_t> VoidPtrSizeMap; - VoidPtrSizeMap activeStrings; -}; -#endif //NDEBUG - - -class AllocatorFreeStoreChecked -{ -public: - static void* allocate(size_t size) //throw (std::bad_alloc) - { -#ifndef NDEBUG - void* newMem = ::operator new(size); - LeakChecker::instance().insert(newMem, size); //test Zbase for memory leaks - return newMem; -#else - return ::operator new(size); -#endif - } - - static void deallocate(void* ptr) - { -#ifndef NDEBUG - LeakChecker::instance().remove(ptr); //check for memory leaks -#endif - ::operator delete(ptr); - } - - static size_t calcCapacity(size_t length) { return std::max<size_t>(16, length + length / 2); } //exponential growth + min size -}; - - -//############################## helper functions ############################################# -#if defined(FFS_WIN) || defined(FFS_LINUX) -//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES -template <class T, template <class, class> class SP, class AP> int cmpFileName(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs); - -struct LessFilename //case-insensitive on Windows, case-sensitive on Linux -{ - template <class T, template <class, class> class SP, class AP> - bool operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const; -}; - -struct EqualFilename //case-insensitive on Windows, case-sensitive on Linux -{ - template <class T, template <class, class> class SP, class AP> - bool operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const; -}; -#endif - -#ifdef FFS_WIN -template <template <class, class> class SP, class AP> -void makeUpper(Zbase<wchar_t, SP, AP>& str); -#endif - -#ifdef FFS_WIN //Windows stores filenames in wide character format -typedef wchar_t Zchar; -#define Zstr(x) L ## x -const Zchar FILE_NAME_SEPARATOR = L'\\'; - -#elif defined FFS_LINUX //Linux uses UTF-8 -typedef char Zchar; -#define Zstr(x) x -const Zchar FILE_NAME_SEPARATOR = '/'; - -#else -#error define platform you are in: FFS_WIN or FFS_LINUX -#endif - -//"The reason for all the fuss above" - Loki/SmartPtr -typedef Zbase<Zchar, StorageRefCountThreadSafe, AllocatorFreeStoreChecked> Zstring; //for use with file names - - - - - - - - - - - - - - - - - - - - - - - - - - -//################################# inline implementation ######################################## -#if defined(FFS_WIN) || defined(FFS_LINUX) -namespace z_impl -{ -int compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB); -void makeUpperCaseWin(wchar_t* str, size_t size); -} - - -template <class T, template <class, class> class SP, class AP> -inline -int cmpFileName(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) -{ -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()); -#elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()); //POSIX filenames don't have embedded 0 -#endif -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool LessFilename::operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const -{ -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()) < 0; -#elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()) < 0; //POSIX filenames don't have embedded 0 -#endif -} - - -template <class T, template <class, class> class SP, class AP> -inline -bool EqualFilename::operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const -{ -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()) == 0; -#elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()) == 0; //POSIX filenames don't have embedded 0 -#endif -} -#endif //defined(FFS_WIN) || defined(FFS_LINUX) - - -#ifdef FFS_WIN -template <template <class, class> class SP, class AP> -inline -void makeUpper(Zbase<wchar_t, SP, AP>& str) -{ - z_impl::makeUpperCaseWin(str.begin(), str.length()); -} -#endif - - -namespace std -{ -template<> -inline -void swap(Zstring& rhs, Zstring& lhs) -{ - rhs.swap(lhs); -} -} - -#endif //ZSTRING_H_INCLUDED |