From 106d417de062b88f09cd76ed947dfbb4856cec71 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Fri, 27 Feb 2009 16:41:51 +0100 Subject: [PATCH] StaticAssert added - catch people using silly template sizes for FixedList, PackedList --- applications/test/PackedList/PackedListTest.C | 3 +- .../containers/Lists/FixedList/FixedList.H | 4 + .../containers/Lists/PackedList/PackedList.H | 8 +- src/OpenFOAM/db/error/StaticAssert.H | 87 +++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 src/OpenFOAM/db/error/StaticAssert.H diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C index 442c6dec5b..05f3a077f8 100644 --- a/applications/test/PackedList/PackedListTest.C +++ b/applications/test/PackedList/PackedListTest.C @@ -28,6 +28,7 @@ Description \*---------------------------------------------------------------------------*/ +#include "uLabel.H" #include "IOstreams.H" #include "PackedBoolList.H" @@ -38,7 +39,7 @@ using namespace Foam; int main(int argc, char *argv[]) { - Info<< "PackedList max_bits() = " << PackedList<0>::max_bits() << nl; + Info<< "PackedList max_bits() = " << PackedList<>::max_bits() << nl; Info<< "\ntest allocation with value\n"; PackedList<3> list1(5,1); diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H index 34bc05749f..243d564388 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H @@ -43,6 +43,7 @@ SourceFiles #include "uLabel.H" #include "Hash.H" #include "autoPtr.H" +#include "StaticAssert.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -70,6 +71,9 @@ template class SLList; template class FixedList { + //- Size must be positive (non-zero) and also fit as a signed value + StaticAssert(Size && Size <= INT_MAX); + // Private data //- Vector of values of type T of size Size. diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index 02bdae8da0..af0f5cb5e0 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -76,9 +76,6 @@ Note SeeAlso Foam::DynamicList -ToDo - Checks for bad template parameters (ie, nBits=0, nBits too large)? - SourceFiles PackedListI.H PackedList.C @@ -89,6 +86,7 @@ SourceFiles #define PackedList_H #include "labelList.H" +#include "StaticAssert.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -120,6 +118,10 @@ class PackedList typedef unsigned int StorageType; typedef List StorageList; + //- nBits must be positive (non-zero) and fit within the storage + // For simplicity, assume 8-bit bytes + StaticAssert(nBits && nBits < (sizeof(StorageType) << 3)); + // Private data //- Number of nBits entries diff --git a/src/OpenFOAM/db/error/StaticAssert.H b/src/OpenFOAM/db/error/StaticAssert.H new file mode 100644 index 0000000000..93b1968952 --- /dev/null +++ b/src/OpenFOAM/db/error/StaticAssert.H @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::StaticAssertFailed + +Description + Macros and classes to provide static (compile-time) assertions. + + Ideas from various sources + (http://www.ddj.com/cpp/184401547, http://www.boost.org) + +\*---------------------------------------------------------------------------*/ + +#ifndef StaticAssert_H +#define StaticAssert_H + +namespace Foam +{ + +//- Forward declaration of StaticAssertionFailed. +// Leave as an incomplete class so that sizeof(..) fails +template class StaticAssertionFailed; + +/*---------------------------------------------------------------------------*\ + Class StaticAssertionFailed Declaration +\*---------------------------------------------------------------------------*/ + +//- Specialization for successful assertions +template<> +class StaticAssertionFailed +{}; + + +//- Helper class for handling static assertions +template +class StaticAssertionTest {}; + +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// internal use: +// ~~~~~~~~~~~~~ +// paste together strings, even if an argument is itself a macro +#define StaticAssertMacro(X,Y) StaticAssertMacro1(X,Y) +#define StaticAssertMacro1(X,Y) StaticAssertMacro2(X,Y) +#define StaticAssertMacro2(X,Y) X##Y + +// external use: +// ~~~~~~~~~~~~~ +/** + * @def StaticAssert(Test) + * Assert that some test is true at compile-time +*/ +#define StaticAssert(Test) \ + typedef ::Foam::StaticAssertionTest \ + < \ + sizeof( ::Foam::StaticAssertionFailed< ((Test) ? true : false) > ) \ + > StaticAssertMacro(StaticAssertionTest, __LINE__) + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //