Fix File::nonexistent false leak using SharedSingleton

This commit is contained in:
Vinnie Falco
2013-06-30 03:25:20 -07:00
parent 3fea8a4202
commit 57d0e556d8
10 changed files with 45 additions and 21 deletions

View File

@@ -21,6 +21,32 @@
*/ */
//============================================================================== //==============================================================================
// We need to make a shared singleton or else there are
// issues with the leak detector and order of detruction.
//
class NonexistentHolder : public SharedSingleton <NonexistentHolder>
{
public:
NonexistentHolder ()
: SharedSingleton <NonexistentHolder> (SingletonLifetime::persistAfterCreation)
{
}
static NonexistentHolder* createInstance ()
{
return new NonexistentHolder;
}
File const file;
};
File const& File::nonexistent ()
{
return NonexistentHolder::getInstance ()->file;
}
//------------------------------------------------------------------------------
File::File (const String& fullPathName) File::File (const String& fullPathName)
: fullPath (parseAbsolutePath (fullPathName)) : fullPath (parseAbsolutePath (fullPathName))
{ {
@@ -67,9 +93,6 @@ File& File::operator= (File&& other) noexcept
} }
#endif #endif
const File File::nonexistent;
//============================================================================== //==============================================================================
String File::parseAbsolutePath (const String& p) String File::parseAbsolutePath (const String& p)
{ {
@@ -321,7 +344,7 @@ String File::getFileNameWithoutExtension() const
bool File::isAChildOf (const File& potentialParent) const bool File::isAChildOf (const File& potentialParent) const
{ {
if (potentialParent == File::nonexistent) if (potentialParent == File::nonexistent ())
return false; return false;
const String ourPath (getPathUpToLastSlash()); const String ourPath (getPathUpToLastSlash());
@@ -633,7 +656,7 @@ bool File::hasFileExtension (const String& possibleSuffix) const
File File::withFileExtension (const String& newExtension) const File File::withFileExtension (const String& newExtension) const
{ {
if (fullPath.isEmpty()) if (fullPath.isEmpty())
return File::nonexistent; return File::nonexistent ();
String filePart (getFileName()); String filePart (getFileName());
@@ -914,7 +937,7 @@ public:
const File home (File::getSpecialLocation (File::userHomeDirectory)); const File home (File::getSpecialLocation (File::userHomeDirectory));
const File temp (File::getSpecialLocation (File::tempDirectory)); const File temp (File::getSpecialLocation (File::tempDirectory));
expect (! File::nonexistent.exists()); expect (! File::nonexistent ().exists());
expect (home.isDirectory()); expect (home.isDirectory());
expect (home.exists()); expect (home.exists());
expect (! home.existsAsFile()); expect (! home.existsAsFile());

View File

@@ -53,7 +53,7 @@ public:
/** Creates an (invalid) file object. /** Creates an (invalid) file object.
The file is initially set to an empty path, so getFullPath() will return The file is initially set to an empty path, so getFullPath() will return
an empty string, and comparing the file to File::nonexistent will return an empty string, and comparing the file to File::nonexistent() will return
true. true.
You can use its operator= method to point it at a proper file. You can use its operator= method to point it at a proper file.
@@ -100,7 +100,7 @@ public:
//============================================================================== //==============================================================================
/** This static constant is used for referring to an 'invalid' file. */ /** This static constant is used for referring to an 'invalid' file. */
static const File nonexistent; static File const& nonexistent ();
//============================================================================== //==============================================================================
/** Checks whether the file actually exists. /** Checks whether the file actually exists.

View File

@@ -45,7 +45,7 @@ TemporaryFile::TemporaryFile (const File& target, const int optionFlags)
targetFile (target) targetFile (target)
{ {
// If you use this constructor, you need to give it a valid target file! // If you use this constructor, you need to give it a valid target file!
bassert (targetFile != File::nonexistent); bassert (targetFile != File::nonexistent ());
} }
TemporaryFile::TemporaryFile (const File& target, const File& temporary) TemporaryFile::TemporaryFile (const File& target, const File& temporary)
@@ -74,7 +74,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
{ {
// This method only works if you created this object with the constructor // This method only works if you created this object with the constructor
// that takes a target file! // that takes a target file!
bassert (targetFile != File::nonexistent); bassert (targetFile != File::nonexistent ());
if (temporaryFile.exists()) if (temporaryFile.exists())
{ {

View File

@@ -127,7 +127,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
break; break;
} }
return File::nonexistent; return File::nonexistent ();
} }
//============================================================================== //==============================================================================

View File

@@ -213,7 +213,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
break; break;
} }
return File::nonexistent; return File::nonexistent ();
} }
//============================================================================== //==============================================================================

View File

@@ -213,7 +213,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
break; break;
} }
return File::nonexistent; return File::nonexistent ();
} }
//============================================================================== //==============================================================================

View File

@@ -251,7 +251,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
return File (resultPath.convertToPrecomposedUnicode()); return File (resultPath.convertToPrecomposedUnicode());
} }
return File::nonexistent; return File::nonexistent ();
} }
//============================================================================== //==============================================================================

View File

@@ -88,7 +88,7 @@ namespace WindowsFileHelpers
if (SHGetSpecialFolderPath (0, path, type, FALSE)) if (SHGetSpecialFolderPath (0, path, type, FALSE))
return File (String (path)); return File (String (path));
return File::nonexistent; return File::nonexistent ();
} }
File getModuleFileName (HINSTANCE moduleHandle) File getModuleFileName (HINSTANCE moduleHandle)
@@ -536,7 +536,7 @@ File BEAST_CALLTYPE File::getSpecialLocation (const SpecialLocationType type)
default: default:
bassertfalse; // unknown type? bassertfalse; // unknown type?
return File::nonexistent; return File::nonexistent ();
} }
return WindowsFileHelpers::getSpecialFolderPath (csidlType); return WindowsFileHelpers::getSpecialFolderPath (csidlType);

View File

@@ -30,7 +30,7 @@ PerformanceCounter::PerformanceCounter (const String& name_,
totalTime (0), totalTime (0),
outputFile (loggingFile) outputFile (loggingFile)
{ {
if (outputFile != File::nonexistent) if (outputFile != File::nonexistent ())
{ {
String s ("**** Counter for \""); String s ("**** Counter for \"");
s << name_ << "\" started at: " s << name_ << "\" started at: "
@@ -81,7 +81,7 @@ void PerformanceCounter::printStatistics()
s << newLine; s << newLine;
if (outputFile != File::nonexistent) if (outputFile != File::nonexistent ())
outputFile.appendText (s, false, false); outputFile.appendText (s, false, false);
numRuns = 0; numRuns = 0;

View File

@@ -57,12 +57,13 @@ public:
@param counterName the name used when printing out the statistics @param counterName the name used when printing out the statistics
@param runsPerPrintout the number of start/stop iterations before calling @param runsPerPrintout the number of start/stop iterations before calling
printStatistics() printStatistics()
@param loggingFile a file to dump the results to - if this is File::nonexistent, @param loggingFile a file to dump the results to - if this is
the results are just written to the debugger output File::nonexistent (), the results are just written
to the debugger output
*/ */
PerformanceCounter (const String& counterName, PerformanceCounter (const String& counterName,
int runsPerPrintout = 100, int runsPerPrintout = 100,
const File& loggingFile = File::nonexistent); const File& loggingFile = File::nonexistent ());
/** Destructor. */ /** Destructor. */
~PerformanceCounter(); ~PerformanceCounter();