Added CheckReturn facility to Loki.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@824 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2007-05-09 00:57:06 +00:00
parent 214635bfc1
commit b1a4b3a047
8 changed files with 529 additions and 7 deletions

View file

@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Library", "src\library.vcproj", "{CBDB8E7A-4286-4AE3-A190-BA33D7C53FF0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Factory", "test\Factory\Factory.vcproj", "{925D5863-2F77-41B7-96F1-CC814762C40F}"
@ -57,6 +57,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Function", "test\Function\F
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CachedFactory", "test\CachedFactory\CachedFactory.vcproj", "{8D186AB4-E544-42D6-B192-1AE2C946875E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheckReturn", "test\CheckReturn\CheckReturn.vcproj", "{C0826A05-9143-4545-B5DE-811C188CB54E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -139,6 +141,10 @@ Global
{8D186AB4-E544-42D6-B192-1AE2C946875E}.Debug|Win32.Build.0 = Debug|Win32
{8D186AB4-E544-42D6-B192-1AE2C946875E}.Release|Win32.ActiveCfg = Release|Win32
{8D186AB4-E544-42D6-B192-1AE2C946875E}.Release|Win32.Build.0 = Release|Win32
{C0826A05-9143-4545-B5DE-811C188CB54E}.Debug|Win32.ActiveCfg = Debug|Win32
{C0826A05-9143-4545-B5DE-811C188CB54E}.Debug|Win32.Build.0 = Debug|Win32
{C0826A05-9143-4545-B5DE-811C188CB54E}.Release|Win32.ActiveCfg = Release|Win32
{C0826A05-9143-4545-B5DE-811C188CB54E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

96
include/loki/CheckReturn.h Executable file
View file

@ -0,0 +1,96 @@
////////////////////////////////////////////////////////////////////////////////
// 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>
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 asserts.
///
/// \par Return Type
/// The returned value is copied into CheckReturn rather than accessed via a
/// 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.
////////////////////////////////////////////////////////////////////////////////
template < class Value >
class CheckReturn
{
public:
/// Conversion constructor changes Value type to CheckReturn type.
inline CheckReturn( 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 this assertion fails, then a function failed to check the
// return value from a function call.
assert( m_checked );
}
/// 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$

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="CachedFactory"
ProjectGUID="{925D5863-2F77-41B7-96F1-CC814762C40F}"
ProjectGUID="{8D186AB4-E544-42D6-B192-1AE2C946875E}"
RootNamespace="CachedFactory"
Keyword="Win32Proj"
>

View file

@ -0,0 +1,69 @@
[Project]
FileName=CheckReturn.dev
Name=CheckReturn
UnitCount=2
Type=1
Ver=1
ObjFiles=
Includes=../../include
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=
IsCpp=1
Icon=
ExeOutput=
ObjectOutput=
OverrideOutput=0
OverrideOutputName=CheckReturn.exe
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=1000001000000001000000
[Unit1]
FileName=main.cpp
CompileCpp=1
Folder=CheckReturn
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=..\..\include\loki\CheckReturn.h
CompileCpp=1
Folder=CheckReturn
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0

View file

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="CheckReturn"
ProjectGUID="{C0826A05-9143-4545-B5DE-811C188CB54E}"
RootNamespace="CheckReturn"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
StringPooling="true"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\include\loki\CheckReturn.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

155
test/CheckReturn/main.cpp Executable file
View file

@ -0,0 +1,155 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2007 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.
////////////////////////////////////////////////////////////////////////////////
// $Id$
#include <loki/CheckReturn.h>
#include <iostream>
#include <string>
using namespace std;
// ----------------------------------------------------------------------------
typedef ::Loki::CheckReturn< bool > BoolReturn;
typedef ::Loki::CheckReturn< string > StringReturn;
// ----------------------------------------------------------------------------
bool NoCheckRequired( void )
{
return true;
}
// ----------------------------------------------------------------------------
BoolReturn CheckRequired( void )
{
return BoolReturn( true );
}
// ----------------------------------------------------------------------------
BoolReturn CheckRequired( bool value )
{
// By passing false into CheckRequired, CheckRequired calls an overloaded
// version of CheckRequired, thus demonstrating that one can use a function
// call within the return statement and not have to create a named
// temporary variable.
if ( !value )
return CheckRequired();
return BoolReturn( value );
}
// ----------------------------------------------------------------------------
string GetString( void )
{
return string( "a" );
}
// ----------------------------------------------------------------------------
StringReturn MustUseString( const char * s )
{
return StringReturn( s );
}
// ----------------------------------------------------------------------------
void StringEater( const string & s )
{
(void)s;
}
// ----------------------------------------------------------------------------
int main( unsigned int argc, const char * argv[] )
{
if ( 2 == argc )
{
const char * const a = argv[ argc - 1 ];
// okay to call without storing or using return value.
GetString();
cout << "Called GetString without using return value." << endl;
// Should not assert since caller stores return value.
const string s = MustUseString( a );
cout << "Called MustUseString and stored return value." << endl;
{
// Should not assert since caller passes return value into another
// function, thus converting CheckReturn back into actual type.
StringEater( MustUseString( a ) );
cout <<
"Called MustUseString and passed return value into another function."
<< endl;
}
// This should assert since caller does not check return value.
MustUseString( s.c_str() );
cout << "Should assert before this line! How did we get here?" << endl;
}
// okay to call without storing or using return value.
NoCheckRequired();
cout << "Called NoCheckRequired without using return value." << endl;
// Should not assert since caller stores return value.
bool okay = CheckRequired();
cout << "Called CheckRequired and stored return value." << endl;
if ( CheckRequired( okay ) )
{
cout << "Called CheckRequired and used return value." << endl;
}
{
// Should not assert since caller stores return value ...
BoolReturn checkBool = CheckRequired();
// and then deliberately ignores it before destructor runs.
(bool)checkBool;
cout << "Called CheckRequired, stored return value, and ignored it."
<< endl;
}
{
// This should not assert since caller deliberately chooses to not
// check return value by casting to return value to correct type.
(bool)CheckRequired();
}
{
// This should not assert since caller deliberately chooses to not
// check return value by casting to return value to correct type.
(bool)CheckRequired( false );
cout << "Made a nested call to CheckRequired." << endl;
}
// This should assert since caller does not check return value.
CheckRequired();
cout << "Should assert before this line! How did we get here?" << endl;
return 0;
}
// ----------------------------------------------------------------------------
// $Log$

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="Function"
ProjectGUID="{925D5863-2F77-41B7-96F1-CC814762C40F}"
ProjectGUID="{2DE18D06-0F3A-4C6D-AF2B-40E074B3C3DC}"
RootNamespace="Function"
Keyword="Win32Proj"
>

View file

@ -274,8 +274,6 @@ template<
void testSize()
{
//#define LOKI_ALLOCATOR_PARAMETERS ::Loki::SingleThreaded, 4096, 128, 4, Loki::NoDestroy
typedef Base<Size, void> A;
typedef Base<Size, Loki::SmallObject< ThreadingModel, chunkSize,
maxSmallObjectSize, objectAlignSize, LifetimePolicy, MutexPolicy > > B;