Implementation, tests and first use of rangechecked_cast

This commit is contained in:
eelke 2019-11-04 18:02:48 +01:00
parent c5f6da48ce
commit f875f0f012
8 changed files with 61 additions and 5 deletions

2
.gitignore vendored
View file

@ -4,6 +4,8 @@ build/*
.kdev4/*
local.pri
DIST/
DIST32/
DIST64/
*.autosave
srcdoc/
pglabAll.pro.user.4.8-pre1

View file

@ -12,4 +12,5 @@ QMAKE_CXXFLAGS += /std:c++17
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += BOOST_ENABLE_ASSERT_HANDLER
DEFINES += WIN32_LEAN_AND_MEAN NOMINMAX _WIN32_WINNT=0x0501

View file

@ -1,5 +1,5 @@
#include "BackupFormatModel.h"
#include "rangechecked_cast.h"
#include <vector>
namespace {
@ -61,7 +61,7 @@ BackupFormatModel::BackupFormatModel(QObject *parent)
int BackupFormatModel::rowCount(const QModelIndex &) const
{
int size = g_BackupFormats.size();
int size = rangechecked_cast<int>(g_BackupFormats.size());
return size;
}
@ -79,7 +79,7 @@ QVariant BackupFormatModel::data(const QModelIndex &index, int role) const
const int col = index.column();
if (role == Qt::DisplayRole) {
const auto &item = g_BackupFormats.at(row);
const auto &item = g_BackupFormats.at(rangechecked_cast<size_t>(row));
switch (col) {
case ColumnShort:
result = item.shortFlag;
@ -93,7 +93,7 @@ QVariant BackupFormatModel::data(const QModelIndex &index, int role) const
}
}
else if (role == Qt::ToolTipRole) {
const auto &item = g_BackupFormats.at(row);
const auto &item = g_BackupFormats.at(rangechecked_cast<size_t>(row));
result = item.description;
}
}

View file

@ -1,5 +1,6 @@
#include "ExplainTreeModelItem.h"
#include "json/json.h"
#include "rangechecked_cast.h"
#include <limits>
namespace {
@ -110,7 +111,7 @@ ExplainTreeModelItemPtr ExplainTreeModelItem::child(int row)
int ExplainTreeModelItem::childCount() const
{
return m_childItems.size();
return rangechecked_cast<int>(m_childItems.size());
}
//int ExplainTreeModelItem::columnCount() const

View file

@ -56,6 +56,7 @@ HEADERS += PasswordManager.h \
SqlAstSelectListEntry.h \
SqlAstSelect.h \
SqlAstExpression.h \
rangechecked_cast.h \
std_utils.h \
IntegerRange.h

15
core/rangechecked_cast.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef RANGECHECKED_CAST_H
#define RANGECHECKED_CAST_H
#include <boost/assert.hpp>
#include <limits>
template <typename To, typename From>
To rangechecked_cast(From f)
{
BOOST_ASSERT(f > std::numeric_limits<To>::lowest());
BOOST_ASSERT(f < std::numeric_limits<To>::max());
return static_cast<To>(f);
}
#endif // RANGECHECKED_CAST_H

View file

@ -20,6 +20,7 @@ SOURCES += main.cpp \
tst_escapeConnectionStringValue.cpp \
tst_expected.cpp \
tst_SqlLexer.cpp \
tst_rangechecked_cast.cpp \
tst_scopeguard.cpp \
tst_CsvWriter.cpp \
tst_PasswordManager.cpp \

View file

@ -0,0 +1,35 @@
#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
#include "rangechecked_cast.h"
#include "PrintTo_Qt.h"
using namespace testing;
TEST(rangechecked_cast, in_range)
{
ASSERT_NO_THROW({
int8_t in = 42;
int expected = 42;
auto output = rangechecked_cast<int>(in);
ASSERT_EQ(output, expected);
});
}
TEST(rangechecked_cast, above_max)
{
int64_t in = std::numeric_limits<int>::max() + static_cast<int64_t>(1);
ASSERT_THROW({
rangechecked_cast<int>(in);
},
std::runtime_error);
}
TEST(rangechecked_cast, below_lowest)
{
int64_t in = std::numeric_limits<int>::lowest() - static_cast<int64_t>(1);
ASSERT_THROW({
rangechecked_cast<int>(in);
},
std::runtime_error);
}