From 4f32da182c8b7f85f1a394201f22741ba785c1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Rombauts?= Date: Wed, 13 Dec 2017 08:34:27 +0100 Subject: [PATCH] Add my Utils.h file to define nullptr on C++98 and C++03 compilers --- CMakeLists.txt | 1 + include/SQLiteCpp/Database.h | 23 +++++++------ include/SQLiteCpp/Utils.h | 67 ++++++++++++++++++++++++++++++++++++ src/Database.cpp | 16 ++++----- 4 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 include/SQLiteCpp/Utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b61d153..a121369 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ set(SQLITECPP_INC ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h + ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Utils.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h ) source_group(inc FILES ${SQLITECPP_INC}) diff --git a/include/SQLiteCpp/Database.h b/include/SQLiteCpp/Database.h index e2177c4..977e676 100644 --- a/include/SQLiteCpp/Database.h +++ b/include/SQLiteCpp/Database.h @@ -3,7 +3,7 @@ * @ingroup SQLiteCpp * @brief Management of a SQLite Database Connection. * - * Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com) + * Copyright (c) 2012-2017 Sebastien Rombauts (sebastien.rombauts@gmail.com) * * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt * or copy at http://opensource.org/licenses/MIT) @@ -11,6 +11,7 @@ #pragma once #include +#include // definition of nullptr for C++98/C++03 compilers #include @@ -95,7 +96,7 @@ public: Database(const char* apFilename, const int aFlags = SQLite::OPEN_READONLY, const int aBusyTimeoutMs = 0, - const char* apVfs = NULL); + const char* apVfs = nullptr); /** * @brief Open the provided database UTF-8 filename. @@ -309,10 +310,10 @@ public: * @param[in] aNbArg Number of arguments in the function * @param[in] abDeterministic Optimize for deterministic functions (most are). A random number generator is not. * @param[in] apApp Arbitrary pointer of user data, accessible with sqlite3_user_data(). - * @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal NULL) - * @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc NULL) - * @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc NULL) - * @param[in] apDestroy If not NULL, then it is the destructor for the application data pointer. + * @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal nullptr) + * @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr) + * @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr) + * @param[in] apDestroy If not nullptr, then it is the destructor for the application data pointer. * * @throw SQLite::Exception in case of error */ @@ -337,10 +338,10 @@ public: * @param[in] aNbArg Number of arguments in the function * @param[in] abDeterministic Optimize for deterministic functions (most are). A random number generator is not. * @param[in] apApp Arbitrary pointer of user data, accessible with sqlite3_user_data(). - * @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal NULL) - * @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc NULL) - * @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc NULL) - * @param[in] apDestroy If not NULL, then it is the destructor for the application data pointer. + * @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal nullptr) + * @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr) + * @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr) + * @param[in] apDestroy If not nullptr, then it is the destructor for the application data pointer. * * @throw SQLite::Exception in case of error */ @@ -368,7 +369,7 @@ public: * @note UTF-8 text encoding assumed. * * @param[in] apExtensionName Name of the shared library containing extension - * @param[in] apEntryPointName Name of the entry point (NULL to let sqlite work it out) + * @param[in] apEntryPointName Name of the entry point (nullptr to let sqlite work it out) * * @throw SQLite::Exception in case of error */ diff --git a/include/SQLiteCpp/Utils.h b/include/SQLiteCpp/Utils.h new file mode 100644 index 0000000..fb8d2ea --- /dev/null +++ b/include/SQLiteCpp/Utils.h @@ -0,0 +1,67 @@ +/** + * @file Utils.h + * @ingroup SQLiteCpp + * @brief Shared utility macros and functions. + * + * Copyright (c) 2013-2017 Sebastien Rombauts (sebastien.rombauts@gmail.com) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ +#pragma once + +#include + +/** + * @brief A macro to disallow the copy constructor and operator= functions. + * + * This should be used in the private: declarations for a class + * + * @param[in] TypeName Class name to protect + */ +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#ifdef _MSC_VER +#if _MSC_VER < 1600 +/// A macro to enable the use of the nullptr keyword (NULL on older MSVC compilers, as they do not accept "nullptr_t") +#ifndef nullptr +#define nullptr NULL +#endif // nullptr +#endif // _MSC_VER < 1600 +#else // _MSC_VER +#if (__cplusplus < 201103L) && !defined(__GXX_EXPERIMENTAL_CXX0X__) // before C++11 on GCC4.7 and Visual Studio 2010 +#ifndef HAVE_NULLPTR +#define HAVE_NULLPTR ///< A macro to avoid double definition of nullptr +/** + * @brief nullptr_t is the type of the null pointer literal, nullptr. +*/ +class nullptr_t { +public: + template + inline operator T* () const { ///< convertible to any type of null non-member pointer... + return 0; + } + + template + inline operator T C::* () const { ///< convertible to any type of null member pointer... + return 0; + } + +private: + void operator&() const; ///< Can't take address of nullptr NOLINT +}; + +/** + * @brief Better way to enable nullptr on older GCC/Clang compilers +*/ +const nullptr_t nullptr = {}; +#endif // HAVE_NULLPTR +#endif // (__cplusplus < 201103L) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +#endif // _MSC_VER + +// A macro for snprintf support in Visual Studio +#if _MSC_VER +#define snprintf _snprintf +#endif diff --git a/src/Database.cpp b/src/Database.cpp index 3c0374d..c230210 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -3,7 +3,7 @@ * @ingroup SQLiteCpp * @brief Management of a SQLite Database Connection. * - * Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com) + * Copyright (c) 2012-2017 Sebastien Rombauts (sebastien.rombauts@gmail.com) * * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt * or copy at http://opensource.org/licenses/MIT) @@ -53,8 +53,8 @@ int getLibVersionNumber() noexcept // nothrow Database::Database(const char* apFilename, const int aFlags /* = SQLite::OPEN_READONLY*/, const int aBusyTimeoutMs /* = 0 */, - const char* apVfs /* = NULL*/) : - mpSQLite(NULL), + const char* apVfs /* = nullptr*/) : + mpSQLite(nullptr), mFilename(apFilename) { const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs); @@ -75,10 +75,10 @@ Database::Database(const std::string& aFilename, const int aFlags /* = SQLite::OPEN_READONLY*/, const int aBusyTimeoutMs /* = 0 */, const std::string& aVfs /* = "" */) : - mpSQLite(NULL), + mpSQLite(nullptr), mFilename(aFilename) { - const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? NULL : aVfs.c_str()); + const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? nullptr : aVfs.c_str()); if (SQLITE_OK != ret) { const SQLite::Exception exception(mpSQLite, ret); // must create before closing @@ -126,7 +126,7 @@ void Database::setBusyTimeout(const int aBusyTimeoutMs) // Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...). int Database::exec(const char* apQueries) { - const int ret = sqlite3_exec(mpSQLite, apQueries, NULL, NULL, NULL); + const int ret = sqlite3_exec(mpSQLite, apQueries, nullptr, nullptr, nullptr); check(ret); // Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only) @@ -217,12 +217,12 @@ void Database::loadExtension(const char* apExtensionName, const char *apEntryPoi throw std::runtime_error("sqlite extensions are disabled"); #else -#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18): +#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2017-05-18): // Security warning: // It is recommended that the SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION method be used to enable only this interface. // The use of the sqlite3_enable_load_extension() interface should be avoided to keep the SQL load_extension() // disabled and prevent SQL injections from giving attackers access to extension loading capabilities. - int ret = sqlite3_db_config(mpSQLite, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL); + int ret = sqlite3_db_config(mpSQLite, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, nullptr); #else int ret = sqlite3_enable_load_extension(mpSQLite, 1); #endif