|
From: <ric...@us...> - 2013-06-19 02:23:07
|
Revision: 1184
http://sourceforge.net/p/loki-lib/code/1184
Author: rich_sposato
Date: 2013-06-19 02:23:00 +0000 (Wed, 19 Jun 2013)
Log Message:
-----------
Added SmartAssert to Loki.
Modified Paths:
--------------
trunk/Loki.cbp
trunk/Loki.sln
trunk/Loki.workspace
trunk/include/loki/ScopeGuard.h
Added Paths:
-----------
trunk/include/loki/Concatenate.h
trunk/include/loki/SmartAssert.hpp
trunk/src/SmartAssert.cpp
trunk/test/SmartAssert/
trunk/test/SmartAssert/SmartAssert.cbp
trunk/test/SmartAssert/SmartAssert.vcxproj
trunk/test/SmartAssert/main.cpp
Modified: trunk/Loki.cbp
===================================================================
--- trunk/Loki.cbp 2012-04-03 05:46:56 UTC (rev 1183)
+++ trunk/Loki.cbp 2013-06-19 02:23:00 UTC (rev 1184)
@@ -6,9 +6,9 @@
<Option compiler="cygwin" />
<Build>
<Target title="Debug_GCC">
- <Option output="./lib/GCC/Loki_D.a" prefix_auto="0" extension_auto="0" />
+ <Option output=".\lib\GCC\Loki_D.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
- <Option object_output="obj/Debug_GCC/" />
+ <Option object_output="obj\Debug_GCC\" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
@@ -17,27 +17,27 @@
<Add option="-W" />
<Add option="-DDEBUG" />
<Add directory="." />
- <Add directory="./include" />
- <Add directory="./include/loki" />
+ <Add directory=".\include" />
+ <Add directory=".\include\loki" />
</Compiler>
</Target>
<Target title="Release_GCC">
- <Option output="./lib/GCC/Loki.a" prefix_auto="0" extension_auto="0" />
+ <Option output=".\lib\GCC\Loki.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
- <Option object_output="obj/Release_GCC/" />
+ <Option object_output="obj\Release_GCC\" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-W" />
- <Add directory="./include/loki" />
- <Add directory="./include" />
+ <Add directory=".\include\loki" />
+ <Add directory=".\include" />
</Compiler>
</Target>
<Target title="Debug_Cygwin">
- <Option output="./lib/Cygwin/Loki_D.a" prefix_auto="0" extension_auto="0" />
+ <Option output=".\lib\Cygwin\Loki_D.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
- <Option object_output="obj/Debug_Cygwin/" />
+ <Option object_output="obj\Debug_Cygwin\" />
<Option type="2" />
<Option compiler="cygwin" />
<Option createDefFile="1" />
@@ -45,88 +45,90 @@
<Add option="-W" />
<Add option="-g" />
<Add directory="." />
- <Add directory="./include" />
- <Add directory="./include/loki" />
+ <Add directory=".\include" />
+ <Add directory=".\include\loki" />
</Compiler>
</Target>
<Target title="Release_Cygwin">
- <Option output="./lib/Cygwin/Loki.a" prefix_auto="0" extension_auto="0" />
+ <Option output=".\lib\Cygwin\Loki.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
- <Option object_output="obj/Release_Cygwin/" />
+ <Option object_output="obj\Release_Cygwin\" />
<Option type="2" />
<Option compiler="cygwin" />
<Option createDefFile="1" />
<Compiler>
<Add option="-W" />
- <Add directory="./include/loki" />
- <Add directory="./include" />
+ <Add directory=".\include\loki" />
+ <Add directory=".\include" />
</Compiler>
</Target>
</Build>
- <Unit filename="include/loki/AbstractFactory.h" />
- <Unit filename="include/loki/Allocator.h" />
- <Unit filename="include/loki/AssocVector.h" />
- <Unit filename="include/loki/CachedFactory.h" />
- <Unit filename="include/loki/CheckReturn.h" />
- <Unit filename="include/loki/Checker.h" />
- <Unit filename="include/loki/ConstPolicy.h" />
- <Unit filename="include/loki/DataGenerators.h" />
- <Unit filename="include/loki/EmptyType.h" />
- <Unit filename="include/loki/Factory.h" />
- <Unit filename="include/loki/Function.h" />
- <Unit filename="include/loki/Functor.h" />
- <Unit filename="include/loki/HierarchyGenerators.h" />
- <Unit filename="include/loki/Key.h" />
- <Unit filename="include/loki/LevelMutex.h" />
- <Unit filename="include/loki/LockingPtr.h" />
- <Unit filename="include/loki/LokiExport.h" />
- <Unit filename="include/loki/LokiTypeInfo.h" />
- <Unit filename="include/loki/MultiMethods.h" />
- <Unit filename="include/loki/NullType.h" />
- <Unit filename="include/loki/OrderedStatic.h" />
- <Unit filename="include/loki/Pimpl.h" />
- <Unit filename="include/loki/RefToValue.h" />
- <Unit filename="include/loki/Register.h" />
- <Unit filename="include/loki/SPCachedFactory.h" />
- <Unit filename="include/loki/SafeBits.h" />
- <Unit filename="include/loki/SafeFormat.h" />
- <Unit filename="include/loki/ScopeGuard.h" />
- <Unit filename="include/loki/Sequence.h" />
- <Unit filename="include/loki/Singleton.h" />
- <Unit filename="include/loki/SmallObj.h" />
- <Unit filename="include/loki/SmartPtr.h" />
- <Unit filename="include/loki/StrongPtr.h" />
- <Unit filename="include/loki/ThreadLocal.h" />
- <Unit filename="include/loki/Threads.h" />
- <Unit filename="include/loki/Tuple.h" />
- <Unit filename="include/loki/TypeManip.h" />
- <Unit filename="include/loki/TypeTraits.h" />
- <Unit filename="include/loki/Typelist.h" />
- <Unit filename="include/loki/TypelistMacros.h" />
- <Unit filename="include/loki/Visitor.h" />
- <Unit filename="include/loki/flex/allocatorstringstorage.h" />
- <Unit filename="include/loki/flex/cowstringopt.h" />
- <Unit filename="include/loki/flex/flex_string.h" />
- <Unit filename="include/loki/flex/flex_string_details.h" />
- <Unit filename="include/loki/flex/flex_string_shell.h" />
- <Unit filename="include/loki/flex/simplestringstorage.h" />
- <Unit filename="include/loki/flex/smallstringopt.h" />
- <Unit filename="include/loki/flex/vectorstringstorage.h" />
- <Unit filename="include/loki/static_check.h" />
- <Unit filename="include/loki/yasli/platform.h" />
- <Unit filename="include/loki/yasli/random.h" />
- <Unit filename="include/loki/yasli/yasli_fill_iterator.h" />
- <Unit filename="include/loki/yasli/yasli_memory.h" />
- <Unit filename="include/loki/yasli/yasli_protocols.h" />
- <Unit filename="include/loki/yasli/yasli_traits.h" />
- <Unit filename="include/loki/yasli/yasli_vector.h" />
- <Unit filename="src/LevelMutex.cpp" />
- <Unit filename="src/OrderedStatic.cpp" />
- <Unit filename="src/SafeFormat.cpp" />
- <Unit filename="src/Singleton.cpp" />
- <Unit filename="src/SmallObj.cpp" />
- <Unit filename="src/SmartPtr.cpp" />
- <Unit filename="src/StrongPtr.cpp" />
+ <Unit filename="include\loki\AbstractFactory.h" />
+ <Unit filename="include\loki\Allocator.h" />
+ <Unit filename="include\loki\AssocVector.h" />
+ <Unit filename="include\loki\CachedFactory.h" />
+ <Unit filename="include\loki\CheckReturn.h" />
+ <Unit filename="include\loki\Checker.h" />
+ <Unit filename="include\loki\ConstPolicy.h" />
+ <Unit filename="include\loki\DataGenerators.h" />
+ <Unit filename="include\loki\EmptyType.h" />
+ <Unit filename="include\loki\Factory.h" />
+ <Unit filename="include\loki\Function.h" />
+ <Unit filename="include\loki\Functor.h" />
+ <Unit filename="include\loki\HierarchyGenerators.h" />
+ <Unit filename="include\loki\Key.h" />
+ <Unit filename="include\loki\LevelMutex.h" />
+ <Unit filename="include\loki\LockingPtr.h" />
+ <Unit filename="include\loki\LokiExport.h" />
+ <Unit filename="include\loki\LokiTypeInfo.h" />
+ <Unit filename="include\loki\MultiMethods.h" />
+ <Unit filename="include\loki\NullType.h" />
+ <Unit filename="include\loki\OrderedStatic.h" />
+ <Unit filename="include\loki\Pimpl.h" />
+ <Unit filename="include\loki\RefToValue.h" />
+ <Unit filename="include\loki\Register.h" />
+ <Unit filename="include\loki\SPCachedFactory.h" />
+ <Unit filename="include\loki\SafeBits.h" />
+ <Unit filename="include\loki\SafeFormat.h" />
+ <Unit filename="include\loki\ScopeGuard.h" />
+ <Unit filename="include\loki\Sequence.h" />
+ <Unit filename="include\loki\Singleton.h" />
+ <Unit filename="include\loki\SmallObj.h" />
+ <Unit filename="include\loki\SmartAssert.hpp" />
+ <Unit filename="include\loki\SmartPtr.h" />
+ <Unit filename="include\loki\StrongPtr.h" />
+ <Unit filename="include\loki\ThreadLocal.h" />
+ <Unit filename="include\loki\Threads.h" />
+ <Unit filename="include\loki\Tuple.h" />
+ <Unit filename="include\loki\TypeManip.h" />
+ <Unit filename="include\loki\TypeTraits.h" />
+ <Unit filename="include\loki\Typelist.h" />
+ <Unit filename="include\loki\TypelistMacros.h" />
+ <Unit filename="include\loki\Visitor.h" />
+ <Unit filename="include\loki\flex\allocatorstringstorage.h" />
+ <Unit filename="include\loki\flex\cowstringopt.h" />
+ <Unit filename="include\loki\flex\flex_string.h" />
+ <Unit filename="include\loki\flex\flex_string_details.h" />
+ <Unit filename="include\loki\flex\flex_string_shell.h" />
+ <Unit filename="include\loki\flex\simplestringstorage.h" />
+ <Unit filename="include\loki\flex\smallstringopt.h" />
+ <Unit filename="include\loki\flex\vectorstringstorage.h" />
+ <Unit filename="include\loki\static_check.h" />
+ <Unit filename="include\loki\yasli\platform.h" />
+ <Unit filename="include\loki\yasli\random.h" />
+ <Unit filename="include\loki\yasli\yasli_fill_iterator.h" />
+ <Unit filename="include\loki\yasli\yasli_memory.h" />
+ <Unit filename="include\loki\yasli\yasli_protocols.h" />
+ <Unit filename="include\loki\yasli\yasli_traits.h" />
+ <Unit filename="include\loki\yasli\yasli_vector.h" />
+ <Unit filename="src\LevelMutex.cpp" />
+ <Unit filename="src\OrderedStatic.cpp" />
+ <Unit filename="src\SafeFormat.cpp" />
+ <Unit filename="src\Singleton.cpp" />
+ <Unit filename="src\SmallObj.cpp" />
+ <Unit filename="src\SmartAssert.cpp" />
+ <Unit filename="src\SmartPtr.cpp" />
+ <Unit filename="src\StrongPtr.cpp" />
<Extensions>
<code_completion />
<envvars />
Modified: trunk/Loki.sln
===================================================================
--- trunk/Loki.sln 2012-04-03 05:46:56 UTC (rev 1183)
+++ trunk/Loki.sln 2013-06-19 02:23:00 UTC (rev 1184)
@@ -1,7 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loki", "src\library.vcxproj", "{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Factory", "test\Factory\Factory.vcxproj", "{925D5863-2F77-41B7-96F1-CC814762C40F}"
ProjectSection(ProjectDependencies) = postProject
{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
@@ -23,6 +21,9 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScopeGuard", "test\ScopeGuard\ScopeGuard.vcxproj", "{D5E7BAC2-A961-4ECC-ADA4-82D7510952BA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Singleton", "test\Singleton\Singleton.vcxproj", "{9F489E5D-9F29-4235-A9D4-79B5BA4EC48D}"
ProjectSection(ProjectDependencies) = postProject
@@ -30,8 +31,14 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Visitor", "test\Visitor\Visitor.vcxproj", "{0A696379-10A2-43FB-A26C-B42456FCF657}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flex_string", "test\flex_string\flex_string.vcxproj", "{2022B9AD-34CA-4FDA-80C2-42805FABE65B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SmallObjCompare", "test\SmallObj\SmallObjCompare.vcxproj", "{0A98B714-818C-4DD3-A07C-BDD16399F362}"
ProjectSection(ProjectDependencies) = postProject
@@ -44,8 +51,14 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeletableSingleton", "test\DeletableSingleton\DeletableSingleton.vcxproj", "{B87B3522-7DAA-400D-A47D-A74B9B8B3552}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DefaultAlloc", "test\SmallObj\DefaultAlloc.vcxproj", "{D490B134-B794-42CF-8AF8-9FDA524B9D3B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SmartPtr", "test\SmartPtr\SmartPtr.vcxproj", "{D7AB4FEF-E7AF-443D-93A5-37F323F2042D}"
ProjectSection(ProjectDependencies) = postProject
@@ -58,6 +71,9 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pimpl", "test\Pimpl\Pimpl.vcxproj", "{21D2B291-80F4-476C-A643-B8A7034DF95F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LockingPtr", "test\LockingPtr\LockingPtr.vcxproj", "{25766C3F-C0D8-429F-A212-5FA3537B3E1C}"
ProjectSection(ProjectDependencies) = postProject
@@ -65,10 +81,19 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Function", "test\Function\Function.vcxproj", "{2DE18D06-0F3A-4C6D-AF2B-40E074B3C3DC}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CachedFactory", "test\CachedFactory\CachedFactory.vcxproj", "{8D186AB4-E544-42D6-B192-1AE2C946875E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheckReturn", "test\CheckReturn\CheckReturn.vcxproj", "{C0826A05-9143-4545-B5DE-811C188CB54E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Checker", "test\Checker\Checker.vcxproj", "{B1C04D81-E666-466A-A394-A3E74C830692}"
ProjectSection(ProjectDependencies) = postProject
@@ -81,8 +106,14 @@
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SafeBits", "test\SafeBits\SafeBits.vcxproj", "{ECD7ED50-B99D-44BE-BA38-E17D6110C3E5}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssocVector", "test\AssocVector\AssocVector.vcxproj", "{0605A820-D075-48AC-ABB6-D3FF05D5CD1F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ThreadLocal", "test\ThreadLocal\ThreadLocal.vcxproj", "{27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}"
EndProject
@@ -91,23 +122,24 @@
{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AtomicThread", "test\AtomicThread\AtomicThread.vcxproj", "{BF3C905E-512C-4E64-B737-A6C5B3A18C7E}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Register", "test\Register\Register.vcxproj", "{873CFBF9-0D03-42D5-B2F9-A4C95A15EBCD}"
ProjectSection(ProjectDependencies) = postProject
{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "library", "src\Library.vcxproj", "{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SmartAssert", "test\SmartAssert\SmartAssert.vcxproj", "{DA7BBAE5-1C1A-4B5E-ABF1-2B5090DB2988}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0} = {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Debug|Win32.ActiveCfg = Debug|Win32
- {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Debug|Win32.Build.0 = Debug|Win32
- {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Release|Win32.ActiveCfg = Release|Win32
- {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Release|Win32.Build.0 = Release|Win32
{925D5863-2F77-41B7-96F1-CC814762C40F}.Debug|Win32.ActiveCfg = Debug|Win32
{925D5863-2F77-41B7-96F1-CC814762C40F}.Debug|Win32.Build.0 = Debug|Win32
{925D5863-2F77-41B7-96F1-CC814762C40F}.Release|Win32.ActiveCfg = Release|Win32
@@ -208,14 +240,18 @@
{22A34627-1480-4180-A8B6-4C05E77E27F8}.Debug|Win32.Build.0 = Debug|Win32
{22A34627-1480-4180-A8B6-4C05E77E27F8}.Release|Win32.ActiveCfg = Release|Win32
{22A34627-1480-4180-A8B6-4C05E77E27F8}.Release|Win32.Build.0 = Release|Win32
- {BF3C905E-512C-4E64-B737-A6C5B3A18C7E}.Debug|Win32.ActiveCfg = Debug|Win32
- {BF3C905E-512C-4E64-B737-A6C5B3A18C7E}.Debug|Win32.Build.0 = Debug|Win32
- {BF3C905E-512C-4E64-B737-A6C5B3A18C7E}.Release|Win32.ActiveCfg = Release|Win32
- {BF3C905E-512C-4E64-B737-A6C5B3A18C7E}.Release|Win32.Build.0 = Release|Win32
{873CFBF9-0D03-42D5-B2F9-A4C95A15EBCD}.Debug|Win32.ActiveCfg = Debug|Win32
{873CFBF9-0D03-42D5-B2F9-A4C95A15EBCD}.Debug|Win32.Build.0 = Debug|Win32
{873CFBF9-0D03-42D5-B2F9-A4C95A15EBCD}.Release|Win32.ActiveCfg = Release|Win32
{873CFBF9-0D03-42D5-B2F9-A4C95A15EBCD}.Release|Win32.Build.0 = Release|Win32
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Debug|Win32.Build.0 = Debug|Win32
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Release|Win32.ActiveCfg = Release|Win32
+ {CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}.Release|Win32.Build.0 = Release|Win32
+ {DA7BBAE5-1C1A-4B5E-ABF1-2B5090DB2988}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DA7BBAE5-1C1A-4B5E-ABF1-2B5090DB2988}.Debug|Win32.Build.0 = Debug|Win32
+ {DA7BBAE5-1C1A-4B5E-ABF1-2B5090DB2988}.Release|Win32.ActiveCfg = Release|Win32
+ {DA7BBAE5-1C1A-4B5E-ABF1-2B5090DB2988}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Modified: trunk/Loki.workspace
===================================================================
--- trunk/Loki.workspace 2012-04-03 05:46:56 UTC (rev 1183)
+++ trunk/Loki.workspace 2013-06-19 02:23:00 UTC (rev 1184)
@@ -14,7 +14,7 @@
<Project filename="test/Factory/Factory.cbp" />
<Project filename="test/flex_string/flex_string.cbp" />
<Project filename="test/Function/Function.cbp" />
- <Project filename="test/LevelMutex/LevelMutex.cbp" active="1">
+ <Project filename="test/LevelMutex/LevelMutex.cbp">
<Depends filename="Loki.cbp" />
</Project>
<Project filename="test/Lockable/Lockable.cbp">
@@ -50,5 +50,8 @@
<Project filename="test/SmallObj/SmallObjSingleton.cbp">
<Depends filename="Loki.cbp" />
</Project>
+ <Project filename="test/SmartAssert/SmartAssert.cbp" active="1">
+ <Depends filename="Loki.cbp" />
+ </Project>
</Workspace>
</CodeBlocks_workspace_file>
Added: trunk/include/loki/Concatenate.h
===================================================================
--- trunk/include/loki/Concatenate.h (rev 0)
+++ trunk/include/loki/Concatenate.h 2013-06-19 02:23:00 UTC (rev 1184)
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2013 by Rich Sposato
+// Code covered by the MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef LOKI_MACRO_CONCATENATE_INC_
+#define LOKI_MACRO_CONCATENATE_INC_
+
+// $Id$
+
+/** @note This header file provides a common definition of macros used to
+ concatenate names or numbers together into a single name or number.
+ */
+
+#define LOKI_CONCATENATE_DIRECT(s1, s2) s1##s2
+#define LOKI_CONCATENATE(s1, s2) LOKI_CONCATENATE_DIRECT(s1, s2)
+
+
+#endif
Property changes on: trunk/include/loki/Concatenate.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/include/loki/ScopeGuard.h
===================================================================
--- trunk/include/loki/ScopeGuard.h 2012-04-03 05:46:56 UTC (rev 1183)
+++ trunk/include/loki/ScopeGuard.h 2013-06-19 02:23:00 UTC (rev 1184)
@@ -31,7 +31,9 @@
#include <exception> // needed for calls to uncaught_exception.
#include <loki/RefToValue.h>
+#include <loki/Concatenate.h>
+
/// \defgroup ExceptionGroup Exception-safe code
namespace Loki
@@ -699,8 +701,6 @@
} // 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
Added: trunk/include/loki/SmartAssert.hpp
===================================================================
--- trunk/include/loki/SmartAssert.hpp (rev 0)
+++ trunk/include/loki/SmartAssert.hpp 2013-06-19 02:23:00 UTC (rev 1184)
@@ -0,0 +1,666 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2013 by Rich Sposato
+// Code covered by the MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+////////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef LOKI_SMART_ASSERT_HPP_INCLUDED
+#define LOKI_SMART_ASSERT_HPP_INCLUDED
+
+
+#include <loki/Concatenate.h>
+
+#if defined ( DEBUG ) || defined( DEBUG_ ) || defined( _DEBUG )
+ #define LOKI_SMART_ASSERT_DEBUG
+#endif
+
+#if defined( _MSC_VER )
+ #pragma warning( push )
+ #pragma warning( disable : 4514 )
+ #pragma warning( disable : 4711 )
+#endif
+
+#if !defined( nullptr )
+ #define LOKI_DEFINED_NULLPTR
+ #define nullptr 0
+#endif
+
+
+namespace Loki
+{
+
+// ---------------------------------------------------------------------
+
+/**
+ @par SmartAssert Versus Dumb Assertions
+ Loki's SmartAssert provides features traditional assertions don't.
+ - Add a meaningful message to each assertion.
+ - Output values of variables when assertions fail.
+ - Different severity levels per assertion.
+ - Allows program to do something besides abort when assertions fail.
+ - Can ask user how to respond to assertions instead of just failing.
+ - Customizable output.
+ - Customizable way to ask user for response.
+ - Customizable way to start debugger.
+ - Allows program to do cleanup before dying.
+
+ @par How to Use SmartAssert in 5 Minutes
+ The simplest way to use Loki's SmartAssert is to follow these steps. This is
+ the simplest way to use SmartAssert, and it gives you the same (or similar)
+ behaviors as assert.
+ - Add this line to your file: #include <loki/SmartAssert.hpp>
+ - Replace "assert( condition );" with "LOKI_SMART_ASSERT( condition );"
+ - Make sure you define one of these macros: DEBUG, _DEBUG, or DEBUG_.
+ - Compile and run your program.
+
+ @par Adding Messages to your Assertions.
+ SmartAssert can output simple C-style strings as messages when an assertion
+ fails. Each assertion may have only one message. If you add more than one,
+ then only the right-most message is sent to output. To add a simple message
+ to your assertions, use the .Msg() function.
+ @code
+ LOKI_SMART_ASSERT( cond ).Msg( "Something is rotten in the state of Denmark." );
+ @endcode
+
+ @par Adding Variables to Your Assertions.
+ You can make SmartAssert output the values of variables by adding each
+ variable within a pair of parantheses. It will output them in the same order
+ they were added. You may chain as many variables to the assertion, but you
+ may only place fundamental types in the assertion. You can put them in any
+ order, but SmartAssert will store and output them in the reverse order in
+ which you add them. (i.e. Leftmost variables get outputted last, and
+ rightmost ones get outputted first.) Storing them in reverse order makes an
+ efficiency gain of O(n) over O(n*n).
+ @code
+ LOKI_SMART_ASSERT( cond )( a )( b );
+ LOKI_SMART_ASSERT( cond )( a )( e )( c )( b )( d );
+ @endcode
+
+ SmartAssert won't know the purpose of those variables; only their type and
+ value. You can make SmartAssert output the names of the variables by using
+ the "stringify" preprocessor operator. This causes SmartAssert to create a
+ separate storage for the name and the variable itself.
+ @code
+ LOKI_SMART_ASSERT( cond )( a )( "a" )( b )( "b" );
+ LOKI_SMART_ASSERT( cond )( a )( "a" )( e )( "e" )( b )( "b" );
+ @endcode
+
+ @par Setting the Severity Level
+ Assertions treat all error conditions as an excuse to commit suicide. That
+ one-size-fits-all solution seems overly drastic for minor errors. At least
+ SmartAssert gives the developer more detailed output to help understand why
+ the program died.
+
+ SmartAssert provides multiple severity levels so developers have more options
+ besides seeing their programs die. The basic options are to start a debugger,
+ ignore the assertion that time, ignore it as long as the program runs, or
+ stop the program. The four severity levels and their effects are:
+ - Info: Just output the assertion info and continue on.
+ - Warn: Ask user to either ignore now, ignore always, or start debugger.
+ - Error: Same as above, but also give user option to abort program.
+ - Fatal: Program always ends when assertion fails and never asks user.
+
+ SmartAssert's default severity level is Fatal so you can use it as a drop-in
+ replacement for assert and still get the same behavior.
+
+ Here are some example calls to set the severity level. As you can see, the
+ calls may occur in any order within the assertion.
+ @code
+ LOKI_SMART_ASSERT( cond )( a )( b ).Info();
+ LOKI_SMART_ASSERT( cond ).Warn()( a )( b );
+ LOKI_SMART_ASSERT( cond )( a ).Error().( b );
+ LOKI_SMART_ASSERT( cond ).Fatal().Msg( "Goodbye cruel world!" );
+ LOKI_SMART_ASSERT( cond )( d ); // No severity level implies Fatal!
+ @endcode
+
+ You could specify more than one severity level, but only the rightmost call
+ matters. In this example, Info() is further to the right so it overrides the
+ Fatal() call.
+ @code
+ LOKI_SMART_ASSERT( cond ).Fatal()( a )( b ).Info();
+ @endcode
+
+ @par User Intervention.
+ Since SmartAssert's default behaviors mimic assert, it normally doesn't ask
+ the user how to respond to an assertion failure. SmartAssert asks the user
+ only if the developer puts a call to operator() at the end of the assertion.
+ There is no need to ask the user to intervene if the severity level is Info.
+ If you write a policy class to either ask the user or call the debugger, you
+ should always add the call to operator().
+ @code
+ LOKI_SMART_ASSERT( cond ).Warn()( a )(); // Asks user to intervene.
+ LOKI_SMART_ASSERT( cond ).Warn()( a ); // Does not ask user.
+ @endcode
+
+ @par Write Your Own Policy.
+ Many parts of Loki were implemented using policy-based software design, and
+ SmartAssert follows that tradition. SmartAssert has a default policy that
+ mimics the behaviors of assert. If you want to make your own policy class,
+ write that class to have the same function signatures as
+ CommandLineAssertPolicy, and use the LOKI_SMART_ASSERT_POLICIED macro instead
+ of LOKI_SMART_ASSERT.
+
+ @par Potential Policies
+ - To call a special debugger rather than the default one.
+ - To send output to a log file instead of to cout.
+ - To create a popup dialog box to ask the user.
+ - To attempt last moment cleanup before the program dies.
+
+ @code
+ class MyPolicy
+ {
+ static void Output( const SmartAssertBase * asserter );
+ static void Debugger( const SmartAssertBase * asserter );
+ static SmartAssertBase::UserResponse AskUser( const SmartAssertBase * asserter );
+ static void AbortNow( const SmartAssertBase * asserter );
+ };
+ LOKI_SMART_ASSERT_POLICIED( cond, MyPolicy );
+ @endcode
+
+ @par Thread Safety.
+ Each SmartAssert object is declared locally within a function, so it is only
+ accessible by the thread executing it. However, each SmartAssert makes its
+ own static boolean flag for whether to ignore its future failures. That
+ boolean flag is not thread_local, so telling SmartAssert to ignore it each
+ time applies to all threads. SmartAssert relies on a policy class, so it is
+ only as thread-safe as the functions in its policy class.
+
+ @par Exception Safety.
+ SmartAssert wraps calls to the policy class within try-catch blocks. If an
+ exception occurs for Info or Warning level conditions, SmartAssert stops
+ processing the assertion and allows the calling function to continue. If an
+ exception occurs when processing an Error or Fatal assertion, SmartAssert
+ will abort immediately.
+
+ @par Memory Usage.
+ SmartAssert does not allocate any memory or other resources, but functions
+ within policy classes might.
+
+ @par Run-Time Efficiency.
+ No function call or operation within SmartAssert takes more than O(n) steps,
+ where n is the number of variables passed into SmartAssert. Most actions
+ complete in constant time. Functions in policy classes may not have the same
+ low run-time efficiency.
+*/
+
+// ---------------------------------------------------------------------
+
+/** @class AssertInfo Stores extra info user wants to pass into assertion.
+ This class has one constructor for each primitive data type so developers
+ can pass any primitive variable into the assert.
+ */
+class AssertInfo
+{
+public:
+
+ /** @enum DataTypeTag One tag for each primitive data type, plus a
+ few for pointers to char data types.
+ */
+ enum DataTypeTag
+ {
+ Unknown = 0,
+ Boolean,
+ JustChar,
+ SignedChar,
+ UnsignedChar,
+ SignedShort,
+ UnsignedShort,
+ JustInt,
+ SignedInt,
+ UnsignedInt,
+ Long,
+ UnsignedLong,
+ LongInt,
+ UnsignedLongInt,
+ CharPtr,
+ SignedCharPtr,
+ UnsignedCharPtr,
+ VoidPtr,
+ Float,
+ Double,
+ LongDouble,
+ };
+
+ static const char * GetName( DataTypeTag tag );
+
+ /// @union DataValue Can be configured as any primitive data type.
+ union DataValue
+ {
+ bool m_bool;
+ char m_char;
+ signed char m_s_char;
+ unsigned char m_u_char;
+ signed short int m_s_short;
+ unsigned short int m_u_short;
+ int m_int;
+ unsigned int m_u_int;
+ long m_long;
+ unsigned long m_u_long;
+ signed long long int m_s_long_int;
+ unsigned long long int m_u_long_int;
+ const char * m_p_char;
+ const signed char * m_p_s_char;
+ const unsigned char * m_p_u_char;
+ const void * m_p_v;
+ float m_float;
+ double m_double;
+ long double m_l_double;
+
+ DataValue() : m_bool( true ) {}
+ DataValue( const bool v ) : m_bool( v ) {}
+ DataValue( const char v ) : m_char( v ) {}
+ DataValue( const signed char v ) : m_s_char( v ) {}
+ DataValue( const unsigned char v ) : m_u_char( v ) {}
+ DataValue( const signed short int v ) : m_s_short( v ) {}
+ DataValue( const unsigned short int v ) : m_u_short( v ) {}
+ DataValue( const int v ) : m_int( v ) {}
+ DataValue( const unsigned int v ) : m_u_int( v ) {}
+ DataValue( const long v ) : m_long( v ) {}
+ DataValue( const unsigned long v ) : m_u_long( v ) {}
+ DataValue( const long long int v ) : m_s_long_int( v ) {}
+ DataValue( const unsigned long long int v ) : m_u_long_int( v ) {}
+ DataValue( const char * v ) : m_p_char( v ) {}
+ DataValue( const signed char * v ) : m_p_s_char( v ) {}
+ DataValue( const unsigned char * v ) : m_p_u_char( v ) {}
+ DataValue( const void * v ) : m_p_v( v ) {}
+ DataValue( const float v ) : m_float( v ) {}
+ DataValue( const double v ) : m_double( v ) {}
+ DataValue( const long double v ) : m_l_double( v ) {}
+
+ void Output( DataTypeTag type ) const;
+ };
+
+ AssertInfo() : m_type( Unknown ), m_value(), m_next( nullptr ) {}
+ AssertInfo( bool v ) : m_type( Boolean ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( char v ) : m_type( JustChar ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( signed char v ) : m_type( SignedChar ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( unsigned char v ) : m_type( UnsignedChar ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( signed short v ) : m_type( SignedShort ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( unsigned short v ) : m_type( UnsignedShort ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( signed int v ) : m_type( SignedInt ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( unsigned int v ) : m_type( UnsignedInt ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( long v ) : m_type( Long ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( unsigned long v ) : m_type( UnsignedLong ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( long long int v ) : m_type( LongInt ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( unsigned long long int v ) : m_type( UnsignedLongInt ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( const char * v ) : m_type( CharPtr ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( const signed char * v ) : m_type( SignedCharPtr ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( const unsigned char * v ) : m_type( UnsignedCharPtr ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( const void * v ) : m_type( VoidPtr ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( float v ) : m_type( Float ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( double v ) : m_type( Double ), m_value( v ), m_next( nullptr ) {}
+ AssertInfo( long double v ) : m_type( LongDouble ), m_value( v ), m_next( nullptr ) {}
+
+ /// Function provides default output action.
+ void Output() const;
+
+ DataTypeTag m_type; ///< What type of data this stores.
+ DataValue m_value; ///< Value of that data.
+ mutable const AssertInfo * m_next; ///< Pointer to next piece of info, if any.
+};
+
+// ---------------------------------------------------------------------
+
+/** @class AssertContext Stores info about file, line, and function
+ where assertion occurred. Only two or three of these per SmartAssert.
+
+ @note This class is optimized for storing info about the assertion's
+ location, not for storing general values. Use AssertInfo for storing
+ values of arbitary primitive types.
+ */
+class AssertContext
+{
+public:
+
+ /// Constructs context for source code line within file.
+ AssertContext( const char * description, unsigned int line );
+
+ /// Constructs context for source code filename or function name.
+ AssertContext( const char * description, const char * value );
+
+ /// Function provides default output action.
+ void Output() const;
+
+ unsigned int m_line; ///< Line number within file.
+ const char * m_value; ///< Pointer to either filename or function name.
+ const char * m_description; ///< C-style string for describing piece of context.
+ mutable const AssertContext * m_next; ///< Pointer to next piece of context, if any.
+};
+
+// ---------------------------------------------------------------------
+
+class SmartAssertBase
+{
+public:
+
+ enum SeverityLevel
+ {
+ Info_, ///< Just warn user and do nothing else. (same as Warning and Ignore-Each-Time)
+ Warn_, ///< Give user options: (Ignore Once, Ignore Always, Debug)
+ Error_, ///< Give user options: (Ignore Once, Ignore Always, Debug, Abort)
+ Fatal_ ///< Always abort on failure. User gets no option to choose otherwise.
+ };
+
+ /// @enum Possible replies by the user when asked what to do about assertion.
+ enum UserResponse
+ {
+ /// Program continues as if assertion never happened, and asks
+ /// user what to do when assertion occurs again.
+ IgnoreThisTime = 'I',
+ /// Program continues executing, and never checks assertion for
+ /// the rest of the program's execution. If the program ends and
+ /// restarts, SmartAssert will check it again.
+ IgnoreEachTime = 'E',
+ /// Start the debugger at the place where the assertion failed.
+ DebugNow = 'D',
+ /// End the program now.
+ AbortProgram = 'A'
+ };
+
+ /// Gets one word description of severity level.
+ static const char * GetName( SeverityLevel level );
+
+ /// These three C-style strings contain descriptions used for assertion contexts.
+ static const char * const FileDesc;
+ static const char * const LineDesc;
+ static const char * const FunctionDesc;
+
+ mutable const AssertContext * m_context; /// Linked-list of contexts of where assertion occurred.
+ mutable const AssertInfo * m_info; ///< Linked-list of values provided for output purposes.
+ SeverityLevel m_level; ///< How bad is this assertion?
+ bool * m_ignore; ///< Pointer to ignore-always flag.
+ const char * m_expression; ///< Pointer to C-style string of failed assertion expression.
+ const char * m_message; ///< Simple message made by developer.
+ bool m_handled; ///< True if this assertion was handled before destructor.
+
+protected:
+
+ /// Default constructor is used for release builds. It ignores assertions.
+ SmartAssertBase();
+
+ /** This constructor gets used in debug builds.
+ @param ignore Pointer to boolean flag to ignore this assertion each time.
+ @param expression C-style string showing failed assertion.
+ */
+ SmartAssertBase( bool * ignore, const char * expression );
+
+ /// Destructor handles assertion only when if not handled earlier.
+ virtual ~SmartAssertBase();
+
+ /// Called by derived class to add context information.
+ SmartAssertBase & AddContext( const AssertContext & info );
+
+ /// Called by derived class to add values used to display info about assertion.
+ SmartAssertBase & AddInfo( const AssertInfo & info );
+
+ /// Called to handle assertion failure.
+ void HandleFailure();
+
+ /// Default implementation of code to output information about assertion.
+ virtual void CallOutput() const;
+
+ /// Default implementation of code to call debugger.
+ virtual void CallDebugger() const;
+
+ /// Default implementation of code to ask user what to do.
+ virtual UserResponse AskUser() const;
+
+ /// Default implementation of code to abort program.
+ virtual void AbortNow() const;
+
+ /// Ignore-always flag used by assertions created in release builds.
+ static bool s_alwaysIgnore;
+};
+
+// ---------------------------------------------------------------------
+
+/** @class CommandLineAssertPolicy Default policy for command line programs.
+ Developers can implement their own policies to handle assertions by making a
+ class with the same function signatures as this class. If you write your own
+ policy class, you should also use the LOKI_SMART_ASSERT_POLICIED macro, and
+ not the LOKI_SMART_ASSERT macro.
+*/
+class CommandLineAssertPolicy
+{
+public:
+
+ /// Displays information about assertion to the user.
+ static void Output( const SmartAssertBase * asserter );
+
+ /// Asks user how to handle assertion.
+ static SmartAssertBase::UserResponse AskUser( const SmartAssertBase * asserter );
+
+ /// Calls debugger.
+ static void Debugger( const SmartAssertBase * asserter );
+
+ /// This call should end the program.
+ static void AbortNow( const SmartAssertBase * asserter );
+
+};
+
+// ---------------------------------------------------------------------
+
+/** @class class SmartAssert
+ */
+template< class AssertPolicy >
+class SmartAssert : public SmartAssertBase
+{
+public:
+
+ /// Default constructor used for when assertion passes. Should get optimized away.
+ SmartAssert() : SmartAssertBase() {}
+
+ /// Constructor used when assertion fails.
+ SmartAssert( bool * ignore, const char * expression )
+ : SmartAssertBase( ignore, expression ) {}
+
+ /// Destructor is trivial.
+ virtual ~SmartAssert() {}
+
+ /// Provides simple hard-coded C-style string message for output.
+ SmartAssert & Msg( const char * message ) { m_message = message; return *this; }
+
+ SmartAssert & Info() { m_level = SmartAssertBase::Info_; return *this; }
+ SmartAssert & Warn() { m_level = SmartAssertBase::Warn_; return *this; }
+ SmartAssert & Error() { m_level = SmartAssertBase::Error_; return *this; }
+ SmartAssert & Fatal() { m_level = SmartAssertBase::Fatal_; return *this; }
+
+ /// Called to do non-default actions when assertion fails.
+ void operator ()() { HandleFailure(); }
+
+ /// Adds one piece of information to assertion, generally a variable or result of function call.
+ SmartAssert & operator ()( const AssertInfo & info )
+ {
+ return static_cast< SmartAssert & >( AddInfo( info ) );
+ }
+
+ /// Called to add one piece of context to assertion, such as filename, line, or function name.
+ SmartAssert & Add( const AssertContext & info )
+ {
+ return static_cast< SmartAssert & >( AddContext( info ) );
+ }
+
+private:
+
+ virtual void CallOutput() const
+ {
+ AssertPolicy::Output( dynamic_cast< const SmartAssertBase * >( this ) );
+ }
+
+ virtual void CallDebugger() const
+ {
+ AssertPolicy::Debugger( dynamic_cast< const SmartAssertBase * >( this ) );
+ }
+
+ virtual SmartAssertBase::UserResponse AskUser() const
+ {
+ return AssertPolicy::AskUser( dynamic_cast< const SmartAssertBase * >( this ) );
+ }
+
+ virtual void AbortNow() const
+ {
+ AssertPolicy::AbortNow( dynamic_cast< const SmartAssertBase * >( this ) );
+ }
+
+};
+
+// ---------------------------------------------------------------------
+
+} // namespace Loki
+
+
+/// These lines let Loki put filename and line into AssertContext.
+// note: using 'const char LOKI_SMART_ASSERT_FILE[] = __FILE__'
+// does not work, since __FILE__ = "SmartAssert.hpp"
+#define LOKI_SMART_ASSERT_FILE __FILE__
+#define LOKI_USE_NUMBER_FOR_UNIQUE_NAME __LINE__
+
+
+/** These lines determine if Loki can get the function name into AssertContext.
+ They also declare the macro used for creating unique names for SmartAssert
+ classes and variables.
+ */
+#define LOKI_SMART_ASSERT_FUNCTION_EXISTS
+
+#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000))
+ # define LOKI_SMART_ASSERT_FUNCTION __PRETTY_FUNCTION__
+ # undef LOKI_USE_NUMBER_FOR_UNIQUE_NAME
+ # define LOKI_USE_NUMBER_FOR_UNIQUE_NAME __COUNTER__
+
+#elif defined(__FUNCSIG__)
+ # define LOKI_SMART_ASSERT_FUNCTION __FUNCSIG__
+
+#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
+ # define LOKI_SMART_ASSERT_FUNCTION __FUNC__
+
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
+ # define LOKI_SMART_ASSERT_FUNCTION __func__
+
+#elif (defined __MSC_VER) && (__MSC_VER >= 1300)
+ # define LOKI_SMART_ASSERT_FUNCTION __FUNCDNAME__
+ # undef LOKI_USE_NUMBER_FOR_UNIQUE_NAME
+ # define LOKI_USE_NUMBER_FOR_UNIQUE_NAME __COUNTER__
+
+#elif defined(__IBMCPP__) && (__IBMCPP__ <= 500)
+ # define LOKI_SMART_ASSERT_FUNCTION __FUNCTION__
+
+#elif (defined __HP_aCC) && (__HP_aCC <= 33300)
+ # define LOKI_SMART_ASSERT_FUNCTION __FUNCTION__
+
+#else
+ # undef LOKI_SMART_ASSERT_FUNCTION_EXISTS
+#endif
+
+#define LOKI_MAKE_UNIQUE_NAME( str ) LOKI_CONCATENATE( str, LOKI_USE_NUMBER_FOR_UNIQUE_NAME )
+#define LOKI_SMART_ASSERT_IGNORE_NAME LOKI_MAKE_UNIQUE_NAME( smartAssert_ignore_ )
+#define LOKI_SMART_ASSERT_CLASS_NAME LOKI_MAKE_UNIQUE_NAME( SmartAssert_ )
+#define LOKI_SMART_ASSERT_HIDDEN_CLASS LOKI_SMART_ASSERT_CLASS( LOKI_SMART_ASSERT_CLASS_NAME, LOKI_SMART_ASSERT_IGNORE_NAME )
+
+
+// ---------------------------------------------------------------------
+
+// @note This checks if LOKI_SMART_ASSERT_CONTEXT was defined already in
+// case developers made their own context-creating macro. If you make
+// your own context chain, follow the example here and expect SmartAssert
+// to display the context information in the reverse order of how they
+// are added here. (e.g. - The contexts are added in function-line-file
+// order, but shown in file-line-function order.)
+#ifndef LOKI_SMART_ASSERT_CONTEXT
+
+ #ifdef LOKI_SMART_ASSERT_FUNCTION_EXISTS
+ #define LOKI_SMART_ASSERT_CONTEXT \
+ Add( ::Loki::AssertContext( ::Loki::SmartAssertBase::FunctionDesc, LOKI_SMART_ASSERT_FUNCTION ) ). \
+ Add( ::Loki::AssertContext( ::Loki::SmartAssertBase::LineDesc, __LINE__ ) ). \
+ Add( ::Loki::AssertContext( ::Loki::SmartAssertBase::FileDesc, LOKI_SMART_ASSERT_FILE ) )
+ #else
+ #define LOKI_SMART_ASSERT_CONTEXT \
+ Add( ::Loki::AssertContext( ::Loki::SmartAssertBase::LineDesc, __LINE__ ) ). \
+ Add( ::Loki::AssertContext( ::Loki::SmartAssertBase::FileDesc, LOKI_SMART_ASSERT_FILE ) )
+ #endif
+
+#endif // LOKI_SMART_ASSERT_CONTEXT
+
+
+// ---------------------------------------------------------------------
+
+#define LOKI_MAKE_SMART_ASSERT( class_name, ignore_var_name, expr ) \
+ static bool ignore_var_name = false; \
+ class class_name : public ::Loki::SmartAssert< ::Loki::CommandLineAssertPolicy > \
+ { public: \
+ typedef ::Loki::SmartAssert< ::Loki::CommandLineAssertPolicy > BaseClass; \
+ class_name( bool * ignore, const char * expression ) \
+ : BaseClass( ignore, expression ) {} \
+ virtual ~class_name() {} \
+ }; \
+ if ( ignore_var_name || ( expr ) ) ; else \
+ class_name( &ignore_var_name, #expr ).LOKI_SMART_ASSERT_CONTEXT
+
+
+#ifdef LOKI_SMART_ASSERT_DEBUG
+ #define LOKI_SMART_ASSERT( expr ) \
+ LOKI_MAKE_SMART_ASSERT( LOKI_SMART_ASSERT_CLASS_NAME, LOKI_SMART_ASSERT_IGNORE_NAME, (expr) )
+
+#else
+ #define LOKI_SMART_ASSERT( expr ) \
+ if ( true ) ; else \
+ ::Loki::SmartAssert< ::Loki::CommandLineAssertPolicy >()
+ // Do nothing. Compiler should optimize away the else branch.
+#endif
+
+
+// ---------------------------------------------------------------------
+
+#define LOKI_MAKE_SMART_ASSERT_POLICIED( class_name, ignore_var_name, expr, policy ) \
+ static bool ignore_var_name = false; \
+ class class_name : public ::Loki::SmartAssert< policy > \
+ { public: \
+ typedef ::Loki::SmartAssert< policy > BaseClass; \
+ class_name( bool * ignore, const char * expression ) \
+ : BaseClass( ignore, expression ) {} \
+ virtual ~class_name() {} \
+ }; \
+ if ( ignore_var_name || ( expr ) ) ; else \
+ class_name( &ignore_var_name, #expr ).LOKI_SMART_ASSERT_CONTEXT
+
+
+#ifdef LOKI_SMART_ASSERT_DEBUG
+ #define LOKI_SMART_ASSERT_POLICIED( expr, policy ) \
+ LOKI_MAKE_SMART_ASSERT_POLICIED( LOKI_SMART_ASSERT_CLASS_NAME, LOKI_SMART_ASSERT_IGNORE_NAME, (expr), policy )
+
+#else
+ #define LOKI_SMART_ASSERT_POLICIED( expr, policy ) \
+ if ( true ) ; else \
+ ::Loki::SmartAssert< policy >()
+ // Do nothing. Compiler should optimize away the else branch.
+#endif
+
+// ---------------------------------------------------------------------
+
+#if defined( LOKI_DEFINED_NULLPTR )
+ #undef LOKI_DEFINED_NULLPTR
+ #undef nullptr
+#endif
+
+#if defined( _MSC_VER )
+ #pragma warning( pop )
+#endif
+
+#endif // LOKI_SMART_ASSERT_HPP_INCLUDED
Property changes on: trunk/include/loki/SmartAssert.hpp
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/src/SmartAssert.cpp
===================================================================
--- trunk/src/SmartAssert.cpp (rev 0)
+++ trunk/src/SmartAssert.cpp 2013-06-19 02:23:00 UTC (rev 1184)
@@ -0,0 +1,527 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2013 by Rich Sposato
+// Code covered by the MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+////////////////////////////////////////////////////////////////////////////////
+
+
+#include <loki/SmartAssert.hpp>
+
+#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( WIN32 )
+ #include <Windows.h>
+#endif
+
+#include <iostream>
+
+#include <cassert>
+#include <cstdlib>
+
+#if defined( _MSC_VER )
+ #pragma warning( push )
+ #pragma warning( disable : 4365 )
+ #pragma warning( disable : 4514 )
+ #pragma warning( disable : 4710 )
+ #pragma warning( disable : 4711 )
+#endif
+
+#if !defined( nullptr )
+ #define nullptr 0
+#endif
+
+
+using namespace ::std;
+
+namespace Loki
+{
+
+bool SmartAssertBase::s_alwaysIgnore = true;
+
+const char * const SmartAssertBase::FileDesc = "file";
+const char * const SmartAssertBase::LineDesc = "line";
+const char * const SmartAssertBase::FunctionDesc = "function";
+
+
+// ---------------------------------------------------------------------
+
+const char * AssertInfo::GetName( DataTypeTag tag )
+{
+ switch ( tag )
+ {
+ case Unknown: return "Unknown";
+ case Boolean: return "boolean";
+ case JustChar: return "char";
+ case SignedChar: return "signed char";
+ case UnsignedChar: return "char";
+ case SignedShort: return "signed short";
+ case UnsignedShort: return "unsigned short";
+ case JustInt: return "int";
+ case SignedInt: return "signed int";
+ case UnsignedInt: return "unsigned int";
+ case Long: return "long";
+ case UnsignedLong: return "unsigned long";
+ case LongInt: return "long int";
+ case UnsignedLongInt: return "unsigned long int";
+ case CharPtr: return "char *";
+ case SignedCharPtr: return "signed char *";
+ case UnsignedCharPtr: return "unsigned char *";
+ case VoidPtr: return "void *";
+ case Float: return "float";
+ case Double: return "double";
+ case LongDouble: return "long double";
+ default: break;
+ }
+ return "undefined data type";
+}
+
+// ---------------------------------------------------------------------
+
+void AssertInfo::DataValue::Output( DataTypeTag theType ) const
+{
+ switch ( theType )
+ {
+ case Unknown:
+ {
+ cout << "\t Error! Unknown data type! " << theType;
+ break;
+ }
+ case Boolean:
+ {
+ const char * message = m_bool ? "true" : "false";
+ cout << message;
+ break;
+ }
+ case JustChar:
+ {
+ cout << m_char;
+ break;
+ }
+ case SignedChar:
+ {
+ cout << m_s_char;
+ break;
+ }
+ case UnsignedChar:
+ {
+ cout << m_u_char;
+ break;
+ }
+ case SignedShort:
+ {
+ cout << m_s_short;
+ break;
+ }
+ case UnsignedShort:
+ {
+ cout << m_u_short;
+ break;
+ }
+ case JustInt:
+ {
+ cout << m_int;
+ break;
+ }
+ case SignedInt:
+ {
+ cout << m_int;
+ break;
+ }
+ case UnsignedInt:
+ {
+ cout << m_u_int;
+ break;
+ }
+ case Long:
+ {
+ cout << m_long;
+ break;
+ }
+ case UnsignedLong:
+ {
+ cout << m_u_long;
+ break;
+ }
+ case LongInt:
+ {
+ cout << m_s_long_int;
+ break;
+ }
+ case UnsignedLongInt:
+ {
+ cout << m_u_long_int;
+ break;
+ }
+ case CharPtr:
+ {
+ cout << m_p_char;
+ break;
+ }
+ case SignedCharPtr:
+ {
+ cout << m_p_s_char;
+ break;
+ }
+ case UnsignedCharPtr:
+ {
+ cout << m_p_u_char;
+ break;
+ }
+ case VoidPtr:
+ {
+ cout << m_p_v;
+ break;
+ }
+ case Float:
+ {
+ cout << m_float;
+ break;
+ }
+ case Double:
+ {
+ cout << m_double;
+ break;
+ }
+ case LongDouble:
+ {
+ cout << m_l_double;
+ break;
+ }
+ default:
+ {
+ cout << "\t Error! Undefined data type! " << theType;
+ break;
+ }
+ }
+}
+
+// ---------------------------------------------------------------------
+
+void AssertInfo::Output() const
+{
+ cout << "\t" << GetName( m_type ) << ": ";
+ m_value.Output( m_type );
+ cout << endl;
+}
+
+// ---------------------------------------------------------------------
+
+AssertContext::AssertContext( const char * description, unsigned int line )
+ : m_line( line )
+ , m_value( nullptr )
+ , m_description( description )
+ , m_next( nullptr )
+{
+}
+
+// ---------------------------------------------------------------------
+
+AssertContext::AssertContext( const char * description, const char * value )
+ : m_line( 0 )
+ , m_value( value )
+ , m_description( description )
+ , m_next( nullptr )
+{
+}
+
+// ---------------------------------------------------------------------
+
+void AssertContext::Output() const
+{
+ cout << m_description << ": ";
+ if ( m_value != nullptr )
+ {
+ cout << m_value;
+ }
+ else
+ {
+ cout << m_line;
+ }
+}
+
+// ---------------------------------------------------------------------
+
+const char * SmartAssertBase::GetName( SeverityLevel level )
+{
+ switch ( level )
+ {
+ case Info_: return "Info";
+ case Warn_: return "Warning";
+ case Error_: return "Error";
+ case Fatal_: return "Fatal";
+ }
+ return "unknown";
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase::SmartAssertBase()
+ : m_context( nullptr )
+ , m_info( nullptr )
+ , m_level( Warn_ )
+ , m_ignore( &s_alwaysIgnore )
+ , m_expression( nullptr )
+ , m_message( nullptr )
+ , m_handled( false )
+{
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase::SmartAssertBase( bool * ignore, const char * expression )
+ : m_context( nullptr )
+ , m_info( nullptr )
+ , m_level( Fatal_ ) ///< @note Default level is fatal to match behavior of assert.
+ , m_ignore( ignore )
+ , m_expression( expression )
+ , m_message( nullptr )
+ , m_handled( false )
+{
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase::~SmartAssertBase()
+{
+ if ( m_handled )
+ {
+ return;
+ }
+
+ try
+ {
+ CallOutput();
+ if ( ( Fatal_ == m_level ) || ( Error_ == m_level ) )
+ {
+ AbortNow();
+ }
+ }
+ catch ( ... )
+ {
+ if ( ( Fatal_ == m_level ) || ( Error_ == m_level ) )
+ {
+ // In other situations, I might allow a destructor to do nothing
+ // when an exception occurs, but since this exception occurred
+ // while processing a failed assertion, it is probably not safe
+ // to ignore the exception. Just end the program abruptly.
+ ::std::abort();
+ }
+ }
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase & SmartAssertBase::AddContext( const AssertContext & context )
+{
+ // Contexts are always added to the head of the linked-list since that
+ // is cheaper than traversing the list every time, but the list is in
+ // reverse order from how the entries are declared.
+ assert( m_context != &context );
+ context.m_next = m_context;
+ m_context = &context;
+ return *this;
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase & SmartAssertBase::AddInfo( const AssertInfo & info )
+{
+ // AssertInfo's are always added to the head of the linked-list since
+ // that is cheaper than traversing the list every time, but the list
+ // is in reverse order from how the entries are declared.
+ assert( m_info != &info );
+ info.m_next = m_info;
+ m_info = &info;
+ return *this;
+}
+
+// ---------------------------------------------------------------------
+
+void SmartAssertBase::CallOutput() const
+{
+ CommandLineAssertPolicy::Output( this );
+}
+
+// ---------------------------------------------------------------------
+
+void SmartAssertBase::CallDebugger() const
+{
+ CommandLineAssertPolicy::Debugger( this );
+}
+
+// ---------------------------------------------------------------------
+
+SmartAssertBase::UserResponse SmartAssertBase::AskUser() const
+{
+ return CommandLineAssertPolicy::AskUser( this );
+}
+
+// ---------------------------------------------------------------------
+
+void SmartAssertBase::AbortNow() const
+{
+ CommandLineAssertPolicy::AbortNow( this );
+}
+
+// ---------------------------------------------------------------------
+
+void SmartAssertBase::HandleFailure()
+{
+ m_handled = true;
+
+ try
+ {
+ if ( Info_ == m_level )
+ {
+ CallOutput();
+ return;
+ }
+ CallOutput();
+ if ...
[truncated message content] |