I felt that the compiler was too kind to me, so I enabled a big pile of warnings

Wed, 22 Jun 2022 16:53:35 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Wed, 22 Jun 2022 16:53:35 +0300
changeset 250
2837b549e616
parent 249
37d3c819cafa
child 251
94b0a30a1886

I felt that the compiler was too kind to me, so I enabled a big pile of warnings

CMakeLists.txt file | annotate | diff | comparison | revisions
src/algorithm/earcut.h file | annotate | diff | comparison | revisions
src/circularprimitive.h file | annotate | diff | comparison | revisions
src/colors.cpp file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/document.cpp file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/geometry.cpp file | annotate | diff | comparison | revisions
src/gl/basicshaderprogram.cpp file | annotate | diff | comparison | revisions
src/gl/basicshaderprogram.h file | annotate | diff | comparison | revisions
src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/gl/gridprogram.cpp file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/ldrawalgorithm.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/messagelog.cpp file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/polygoncache.cpp file | annotate | diff | comparison | revisions
src/settings.h file | annotate | diff | comparison | revisions
src/typeconversions.h file | annotate | diff | comparison | revisions
src/ui/circletooloptionswidget.cpp file | annotate | diff | comparison | revisions
src/version.cpp file | annotate | diff | comparison | revisions
src/version.h file | annotate | diff | comparison | revisions
src/vertexmap.cpp file | annotate | diff | comparison | revisions
src/widgets/matrixeditor.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Jun 22 16:13:15 2022 +0300
+++ b/CMakeLists.txt	Wed Jun 22 16:53:35 2022 +0300
@@ -141,9 +141,20 @@
 	if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG")
 	endif()
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wunused")
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-implicit-fallthrough")
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-noexcept-type")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat-nonliteral -Wnonnull -Wnonnull-compare -Wnull-dereference -Winfinite-recursion -Wunused-const-variable=1 -Wuninitialized -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-branches -Wshadow")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-loop-optimizations -Wundef -Wmissing-field-initializers")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wcast-align -Wcast-function-type -Wconversion")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-declarations -Wdate-time")
+endif()
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcovered-switch-default -Wextra-semi -Wgnu -Wmicrosoft")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsometimes-uninitialized -Wstring-concatenation -Wstring-conversion -Wsuggest-override")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override -Wundefined-func-template -Wundefined-reinterpret-cast")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized-const-reference -Wunreachable-code -Wunreachable-code-break -Wunreachable-code-return")
 endif()
 qt5_add_resources(LDFORGE_QRC ${LDFORGE_RESOURCES})
 qt5_wrap_ui(LDFORGE_FORMS_HEADERS ${LDFORGE_FORMS})
--- a/src/algorithm/earcut.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/algorithm/earcut.h	Wed Jun 22 16:53:35 2022 +0300
@@ -15,7 +15,7 @@
 
 template <std::size_t I, typename T> struct nth {
     inline static typename std::tuple_element<I, T>::type
-    get(const T& t) { return std::get<I>(t); };
+    get(const T& t) { return std::get<I>(t); }
 };
 
 }
--- a/src/circularprimitive.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/circularprimitive.h	Wed Jun 22 16:53:35 2022 +0300
@@ -11,7 +11,7 @@
 	const auto xform = [&circ](const glm::vec2& p, float y){
 		return glm::vec3{circ.transformation * glm::vec4{p.x, y, p.y, 1}};
 	};
-	const glm::vec3 origin = xform({0, 0}, 0);
+	const glm::vec3 primitiveOrigin = xform({0, 0}, 0);
 	const bool invertedMatrix = (glm::determinant(circ.transformation) < 0) != circ.inverted;
 	switch(circ.type) {
 	case CircularPrimitive::Circle:
@@ -23,7 +23,7 @@
 	case CircularPrimitive::Disc:
 		ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
 		(const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
-			fn(triangle(origin, xform(p1, 0), xform(p2, 0)));
+			fn(triangle(primitiveOrigin, xform(p1, 0), xform(p2, 0)));
 		});
 		break;
 	case CircularPrimitive::Cylinder:
--- a/src/colors.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/colors.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -108,7 +108,7 @@
 {
 	if (isDirectColor(color)) {
 		const std::array<int, 3> rgb = directColorRgb(color);
-		return (luma(rgb[0], rgb[1], rgb[2]) < 0.4) ? Qt::white : Qt::black;
+		return (luma(rgb[0], rgb[1], rgb[2]) < 102) ? Qt::white : Qt::black;
 	}
 	else {
 		return colorFace(color, colorTable);
--- a/src/colors.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/colors.h	Wed Jun 22 16:53:35 2022 +0300
@@ -82,7 +82,7 @@
 template<typename T>
 constexpr T luma(T r, T g, T b)
 {
-	return 0.2126 * r + 0.7152 * g + 0.0722 * b;
+	return static_cast<T>(0.2126 * r + 0.7152 * g + 0.0722 * b);
 }
 
 //! @brief Checks whether or not the specified color index is a direct color
--- a/src/document.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/document.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -28,12 +28,12 @@
 // Make mapbox::earcut work with glm::vec3
 template<> struct mapbox::util::nth<0, glm::vec3>
 {
-	static constexpr float get(const glm::vec3& t) { return t.x; };
+	static constexpr float get(const glm::vec3& t) { return t.x; }
 };
 
 template<> struct mapbox::util::nth<1, glm::vec3>
 {
-	static constexpr float get(const glm::vec3& t) { return t.y; };
+	static constexpr float get(const glm::vec3& t) { return t.y; }
 };
 
 EditTools::EditTools(QObject* parent) :
@@ -46,14 +46,14 @@
 {
 }
 
-void EditTools::setEditMode(EditingMode mode)
+void EditTools::setEditMode(EditingMode newMode)
 {
-	this->mode = mode;
+	this->mode = newMode;
 }
 
-void EditTools::setGridMatrix(const glm::mat4& gridMatrix)
+void EditTools::setGridMatrix(const glm::mat4& newGridMatrix)
 {
-	this->gridMatrix = gridMatrix;
+	this->gridMatrix = newGridMatrix;
 	this->gridPlane = planeFromTriangle({
 		this->gridMatrix * glm::vec4{0, 0, 0, 1},
 		this->gridMatrix * glm::vec4{1, 0, 0, 1},
@@ -101,7 +101,7 @@
 	const PartRenderer* renderer)
 {
 	QVector<QPointF> points2d;
-	points2d.reserve(worldPoints.size());
+	points2d.reserve(static_cast<int>(worldPoints.size()));
 	for (const glm::vec3& point : worldPoints)
 	{
 		points2d.push_back(renderer->modelToScreenCoordinates(point));
@@ -330,7 +330,7 @@
 	struct boundaryinfo { indextype third; std::size_t triangleid; };
 	std::map<indexpair, boundaryinfo> boundaries;
 	for (std::size_t i = 0; i < indices.size(); i += 3) {
-		const auto add = [&](int o1, int o2, int o3){
+		const auto add = [&](const std::size_t o1, const std::size_t o2, const std::size_t o3){
 			const auto key = std::make_pair(indices[i + o1], indices[i + o2]);
 			boundaries[key] = {indices[i + o3], i};
 		};
--- a/src/document.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/document.h	Wed Jun 22 16:53:35 2022 +0300
@@ -31,7 +31,7 @@
 	CircleMode
 };
 
-Q_DECLARE_METATYPE(EditingMode);
+Q_DECLARE_METATYPE(EditingMode)
 
 struct AppendToModel
 {
@@ -40,7 +40,7 @@
 
 struct DeleteFromModel
 {
-	int position;
+	std::size_t position;
 };
 
 using ModelAction = std::variant<AppendToModel, DeleteFromModel>;
--- a/src/geometry.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/geometry.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -217,11 +217,11 @@
 
 bool isConvex(const std::vector<glm::vec3>& polygon)
 {
-	const int n = polygon.size();
+	const std::size_t n = polygon.size();
 	auto polygonRing = iter::ring(polygon, n);
 	std::vector<glm::vec3> crosses;
 	crosses.resize(n);
-	for (int i = 0; i < n; i += 1)
+	for (std::size_t i = 0; i < n; i += 1)
 	{
 		crosses[i] = glm::cross(polygonRing[i - 1] - polygonRing[i], polygonRing[i + 1] - polygonRing[i]);
 	}
--- a/src/gl/basicshaderprogram.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/basicshaderprogram.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -52,8 +52,9 @@
 		this->vertexArrayObject.bind();
 		for (std::size_t i = 0; i < attributeSpecs.size(); ++i) {
 			const auto& spec = attributeSpecs[i];
-			this->program->enableAttributeArray(i);
-			this->program->setAttributeBuffer(i, spec.type, spec.offset, spec.tuplesize, spec.stride);
+			const int attr = narrow<int>(signed_cast(i));
+			this->program->enableAttributeArray(attr);
+			this->program->setAttributeBuffer(attr, spec.type, spec.offset, spec.tuplesize, spec.stride);
 		}
 		this->vertexArrayObject.release();
 		this->buffer.release();
@@ -88,9 +89,9 @@
 void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size)
 {
 	this->buffer.bind();
-	this->buffer.allocate(data, count * size);
+	this->buffer.allocate(data, narrow<int>(signed_cast(count * size)));
 	this->buffer.release();
-	this->vertexCount = count;
+	this->vertexCount = narrow<int>(signed_cast(count));
 }
 
 void BasicShader::draw(GLenum drawMode)
--- a/src/gl/basicshaderprogram.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/basicshaderprogram.h	Wed Jun 22 16:53:35 2022 +0300
@@ -19,7 +19,7 @@
 	QOpenGLShader fragmentShader;
 	std::unique_ptr<gl::ShaderProgram> program = nullptr;
 	QOpenGLVertexArrayObject vertexArrayObject;
-	std::size_t vertexCount = 0;
+	int vertexCount = 0;
 public:
 	BasicShader();
 	~BasicShader();
--- a/src/gl/common.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/common.h	Wed Jun 22 16:53:35 2022 +0300
@@ -41,9 +41,9 @@
 	virtual void mvpMatrixChanged(const glm::mat4& mvpMatrix) = 0;
 	virtual void mouseMoved(const QMouseEvent*){}
 	virtual void mouseClick(const QMouseEvent*){}
-	void setRendererPointer(class PartRenderer* renderer)
+	void setRendererPointer(class PartRenderer* newRenderer)
 	{
-		this->renderer = renderer;
+		this->renderer = newRenderer;
 	}
 };
 
--- a/src/gl/compiler.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/compiler.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -25,7 +25,7 @@
 #include "invert.h"
 #include "ring.h"
 
-static const char* vertexShaderSource = R"(
+constexpr char VERTEX_SHADER_SOURCE[] = R"(
 #version 330 core
 
 layout(location=0) in vec3 position;
@@ -97,7 +97,7 @@
 }
 )";
 
-static const char* fragmentShaderSource = R"(
+constexpr char FRAGMENT_SHADER_SOURCE[] = R"(
 #version 330 core
 
 in vec4 vColor;
@@ -198,7 +198,7 @@
 	if (not modelShaders->initialized) {
 		for (auto& shader : modelShaders->shaderObjects) {
 			shader.program = std::make_unique<QOpenGLShaderProgram>();
-			gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource);
+			gl::buildShaders(shader.program.get(), VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);
 			shader.program->bind();
 			shader.buffer.create();
 			shader.buffer.bind();
--- a/src/gl/gridprogram.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/gridprogram.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -55,7 +55,7 @@
 constexpr auto calcGridData()
 {
 	std::array<glm::vec2, 8 * extent + 4> result;
-	int ix = 0;
+	std::size_t ix = 0;
 	for (int i = -extent; i <= extent; i += 1) {
 		result[ix++] = {i, -extent};
 		result[ix++] = {i, extent};
--- a/src/gl/partrenderer.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/gl/partrenderer.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -423,7 +423,7 @@
 		this->viewMatrix * this->modelMatrix,
 		this->projectionMatrix,
 		this->viewportVector);
-	return toQPointF(glm::vec2{projected.x, this->height() - projected.y});
+	return toQPointF(glm::vec2{projected.x, static_cast<float>(this->height()) - projected.y});
 }
 
 bool PartRenderer::isDark() const
@@ -446,7 +446,7 @@
 glm::vec3 PartRenderer::unproject(const glm::vec3& win) const
 {
 	return glm::unProject(
-		glm::vec3{win.x, this->height() - win.y, win.z},
+		glm::vec3{win.x, static_cast<float>(this->height()) - win.y, win.z},
 		this->viewMatrix * this->modelMatrix,
 		this->projectionMatrix,
 		viewportVector);
--- a/src/ldrawalgorithm.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/ldrawalgorithm.h	Wed Jun 22 16:53:35 2022 +0300
@@ -19,23 +19,23 @@
 	void makeUnofficial(ModelEditor &editor);
 	*/
 
-	constexpr float circleAngle(int divisions, int i)
+	constexpr float circleAngle(unsigned int divisions, unsigned int i)
 	{
 		constexpr float ofs = 0.5 * pi<>;
-		float factor = -2.0f * pi<> / divisions;
-		return i * factor + ofs;
+		float factor = -2.0f * pi<> / static_cast<float>(divisions);
+		return static_cast<float>(i) * factor + ofs;
 	}
 
-	constexpr glm::vec2 rimpoint(int divisions, int i)
+	constexpr glm::vec2 rimpoint(unsigned int divisions, unsigned int i)
 	{
 		const float angle = circleAngle(divisions, i);
 		return glm::vec2{std::sin(angle), std::cos(angle)};
 	}
 
 	template<typename Fn>
-	void circleAngles(int segments, int divisions, Fn&& fn)
+	void circleAngles(unsigned int segments, unsigned int divisions, Fn&& fn)
 	{
-		for (int i = 0; i < segments; i += 1)
+		for (unsigned int i = 0; i < segments; i += 1)
 		{
 			const float a1 = circleAngle(divisions, i - 1);
 			const float a2 = circleAngle(divisions, i);
@@ -45,7 +45,7 @@
 	}
 
 	template<typename Fn>
-	void circle(int segments, int divisions, Fn&& fn)
+	void circle(unsigned int segments, unsigned int divisions, Fn&& fn)
 	{
 		circleAngles(segments, divisions, [&fn](
 			const float a1,
--- a/src/main.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/main.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -272,7 +272,7 @@
 	}
 	ui->actionDrawAxes->setChecked(renderPreferences->drawAxes);
 	ui->actionWireframe->setChecked(renderPreferences->wireframe);
-};
+}
 
 static gl::RenderPreferences loadRenderPreferences()
 {
@@ -353,7 +353,7 @@
 std::vector<int> rows(const QModelIndexList& indexList)
 {
 	std::vector<int> result;
-	result.reserve(indexList.size());
+	result.reserve(unsigned_cast(indexList.size()));
 	for (const QModelIndex& index : indexList)
 	{
 		result.push_back(index.row());
@@ -467,7 +467,7 @@
 				ModelData* data = findModelData(&documents, modelId);
 				if (data != nullptr) {
 					auto resolveIndex = [&data](const QModelIndex& index){
-						return data->model->idAt(index.row());
+						return data->model->idAt(unsigned_cast(index.row()));
 					};
 					const auto selection = data->itemSelectionModel->selection();
 					const auto indices = fn::map<QSet<ModelId>>(selection.indexes(), resolveIndex);
@@ -606,7 +606,7 @@
 			std::vector<int> selectedRows = rows(ui.modelListView->selectionModel()->selectedRows());
 			std::sort(selectedRows.begin(), selectedRows.end(), std::greater<int>{});
 			for (int row : selectedRows) {
-				executeAction(model, DeleteFromModel{.position = row});
+				executeAction(model, DeleteFromModel{.position = unsigned_cast(row)});
 			}
 		}
 	});
--- a/src/messagelog.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/messagelog.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -9,7 +9,8 @@
 
 void MessageLog::addMessage(const Message& message)
 {
-	this->beginInsertRows({}, this->messages.size(), this->messages.size());
+	const int row = static_cast<int>(this->messages.size());
+	this->beginInsertRows({}, row, row);
 	this->messages.push_back(message);
 	this->endInsertRows();
 }
@@ -32,7 +33,7 @@
 
 int MessageLog::rowCount(const QModelIndex&) const
 {
-	return signed_cast(this->messages.size());
+	return narrow<int>(signed_cast(this->messages.size()));
 }
 
 int MessageLog::columnCount(const QModelIndex&) const
--- a/src/model.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/model.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -47,9 +47,9 @@
 	if (circ.fraction.divisions != 16) {
 		result += QString::number(circ.fraction.divisions) + QStringLiteral("\\");
 	}
-	const int factor = gcd(circ.fraction.segments, circ.fraction.divisions);
-	int num = circ.fraction.segments / factor;
-	int denom = circ.fraction.divisions / factor;
+	const unsigned int factor = gcd(circ.fraction.segments, circ.fraction.divisions);
+	unsigned int num = circ.fraction.segments / factor;
+	unsigned int denom = circ.fraction.divisions / factor;
 	if (denom < 4) {
 		num *= 4 / denom;
 		denom = 4;
@@ -175,30 +175,31 @@
 
 ModelId Model::append(const ModelElement &value)
 {
-	const int position = static_cast<int>(this->body.size());
+	const std::size_t position = this->size();
 	const ModelId id = this->runningId;
 	this->runningId.value += 1;
-	Q_EMIT this->beginInsertRows({}, position, position);
+	const int row = narrow<int>(signed_cast(this->size()));
+	Q_EMIT this->beginInsertRows({}, row, row);
 	this->body.push_back({value, id});
 	this->positions[id] = position;
 	Q_EMIT this->endInsertRows();
 	return id;
 }
 
-const ModelElement &Model::at(int position) const
+const ModelElement &Model::at(std::size_t position) const
 {
 	return this->body[position].data;
 }
 
-ModelId Model::idAt(int position) const
+ModelId Model::idAt(std::size_t position) const
 {
 	return this->body[position].id;
 }
 
-void Model::assignAt(int position, const ModelElement &element)
+void Model::assignAt(std::size_t position, const ModelElement &element)
 {
 	this->body[position].data = element;
-	const QModelIndex index = this->index(position);
+	const QModelIndex index = this->index(narrow<int>(signed_cast(position)));
 	Q_EMIT this->dataChanged(index, index);
 }
 
@@ -216,13 +217,14 @@
 	}
 }
 
-void Model::remove(int index)
+void Model::remove(const std::size_t index)
 {
-	if (index >= 0 and index < this->size()) {
-		Q_EMIT this->beginRemoveRows({}, index, index);
+	if (index <  this->body.size()) {
+		const int row = narrow<int>(signed_cast(index));
+		Q_EMIT this->beginRemoveRows({}, row, row);
 		removeFromMap(this->positions, this->body[index].id);
-		this->body.erase(this->body.begin() + index);
-		for (int i = index; i < this->size(); ++i) {
+		this->body.erase(this->body.begin() + row);
+		for (std::size_t i = index; i < this->body.size(); ++i) {
 			this->positions[this->body[i].id] = i;
 		}
 		Q_EMIT this->endRemoveRows();
@@ -231,12 +233,12 @@
 
 int Model::rowCount(const QModelIndex &) const
 {
-	return this->size();
+	return narrow<int>(signed_cast(this->size()));
 }
 
 QVariant Model::data(const QModelIndex &index, int role) const
 {
-	const int i = index.row();
+	const std::size_t i = unsigned_cast(index.row());
 	const ModelElement& element = this->body[i].data;
 	switch(role)
 	{
@@ -257,12 +259,12 @@
 	}
 }
 
-const ModelElement &Model::operator[](int index) const
+const ModelElement &Model::operator[](std::size_t index) const
 {
 	return this->body[index].data;
 }
 
-int Model::size() const
+std::size_t Model::size() const
 {
 	return this->body.size();
 }
@@ -270,7 +272,7 @@
 void save(const Model &model, QIODevice *device)
 {
 	QTextStream out{device};
-	for (int i = 0; i < model.size(); ++i) {
+	for (std::size_t i = 0; i < model.size(); ++i) {
 		out << modelElementToString(model[i]) << "\r\n";
 	}
 }
--- a/src/model.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/model.h	Wed Jun 22 16:53:35 2022 +0300
@@ -198,7 +198,7 @@
 	constexpr auto operator<=>(const ModelId& other) const = default;
 };
 
-constexpr int qHash(ModelId id)
+constexpr unsigned int qHash(ModelId id)
 {
 	return qHash(id.value);
 }
@@ -211,25 +211,25 @@
 		ModelId id;
 	};
 	std::vector<Entry> body;
-	std::map<ModelId, int> positions;
+	std::map<ModelId, std::size_t> positions;
 	ModelId runningId = {1};
 public:
 	Model(QObject* parent);
 	virtual ~Model();
 	ModelId append(const ModelElement& value);
-	const ModelElement& at(int position) const;
-	ModelId idAt(int position) const;
-	void assignAt(int position, const ModelElement& element);
+	const ModelElement& at(std::size_t position) const;
+	ModelId idAt(std::size_t position) const;
+	void assignAt(std::size_t position, const ModelElement& element);
 	std::optional<int> find(ModelId id) const;
-	void remove(int index);
+	void remove(std::size_t index);
 	int rowCount(const QModelIndex&) const override;
 	QVariant data(const QModelIndex& index, int role) const override;
-	const ModelElement& operator[](int index) const;
-	int size() const;
-	auto operator[](int index) {
+	const ModelElement& operator[](std::size_t index) const;
+	std::size_t size() const;
+	auto operator[](const std::size_t index) {
 		struct {
 			Model& model;
-			int index;
+			const std::size_t index;
 			operator const ModelElement&() {
 				return model.at(index);
 			}
@@ -251,7 +251,7 @@
 template<typename T>
 void iterate(const Model& model, std::function<void(const T&)> fn)
 {
-	for (int i = 0; i < model.size(); ++i) {
+	for (std::size_t i = 0; i < model.size(); ++i) {
 		if (std::holds_alternative<T>(model[i])) {
 			fn(std::get<T>(model[i]));
 		}
--- a/src/polygoncache.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/polygoncache.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -34,7 +34,7 @@
 	GetPolygonsContext* context)
 {
 	std::vector<WithId<PolygonElement>> result;
-	for (int i = 0; i < model->size(); i += 1)
+	for (std::size_t i = 0; i < model->size(); i += 1)
 	{
 		const ModelElement& element = (*model)[i];
 		const ModelId id = model->idAt(i);
--- a/src/settings.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/settings.h	Wed Jun 22 16:53:35 2022 +0300
@@ -18,7 +18,7 @@
 		static const auto& defaultValue() { \
 			static const auto value = DEFVALUE; \
 			return value; \
-		}; \
+		} \
 	};
 
 // -----------------------------------------------------------------------------
--- a/src/typeconversions.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/typeconversions.h	Wed Jun 22 16:53:35 2022 +0300
@@ -85,4 +85,20 @@
 	return reinterpret_cast<reftype>(enu);
 }
 
+//! \brief A version of static_cast that only works if casting from a wider
+//! integer type to a narrower integer type.
+template<typename T, typename R>
+constexpr auto narrow(R x)
+-> std::enable_if_t<sizeof(T) <= sizeof(R) and std::is_signed_v<T> == std::is_signed_v<R>, T>
+{
+	return static_cast<T>(x);
+}
+
+template<typename T, typename R>
+constexpr auto widen(R x)
+-> std::enable_if_t<sizeof(T) >= sizeof(R) and std::is_signed_v<T> == std::is_signed_v<R>, T>
+{
+	return static_cast<T>(x);
+}
+
 #endif // TYPECONVERSIONS_H
--- a/src/ui/circletooloptionswidget.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/ui/circletooloptionswidget.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -40,13 +40,13 @@
 
 unsigned int CircleToolOptionsWidget::segments() const
 {
-	return this->ui.segments->value();
+	return unsigned_cast(this->ui.segments->value());
 }
 
 unsigned int CircleToolOptionsWidget::divisions() const
 {
 	bool ok;
-	const int divs = this->ui.divisions->currentText().toInt(&ok);
+	const unsigned int divs = this->ui.divisions->currentText().toUInt(&ok);
 	if (ok) {
 		return divs;
 	}
@@ -62,11 +62,11 @@
 
 void CircleToolOptionsWidget::handleInputChange()
 {
-	const int olddivs = this->ui.segments->maximum();
-	const int newdivs = this->divisions();
+	const unsigned int olddivs = unsigned_cast(this->ui.segments->maximum());
+	const unsigned int newdivs = this->divisions();
 	if (olddivs != newdivs) {
-		this->ui.segments->setMaximum(newdivs);
-		this->ui.segments->setValue(this->segments() * newdivs / olddivs);
+		this->ui.segments->setMaximum(signed_cast(newdivs));
+		this->ui.segments->setValue(signed_cast(this->segments() * newdivs / olddivs));
 	}
 	const qreal ratio = static_cast<qreal>(this->segments()) / newdivs;
 	this->ui.ratio->setText(QString::number(ratio, 'g', 4));
--- a/src/version.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/version.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -34,8 +34,8 @@
 const QString& fullVersionString()
 {
 #ifdef HG_DATE_VERSION
-	if (::buildType != ReleaseBuild) {
-		static const QString result = makeVersionString(::version) + "-" HG_DATE_VERSION;
+	if (::BUILD_TYPE != ReleaseBuild) {
+		static const QString result = makeVersionString(APPVERSION) + "-" HG_DATE_VERSION;
 		return result;
 	}
 #else
--- a/src/version.h	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/version.h	Wed Jun 22 16:53:35 2022 +0300
@@ -30,8 +30,8 @@
 
 enum BuildType {InternalBuild, ReleaseBuild};
 
-constexpr Version version = {1, 0};
-constexpr BuildType buildType = InternalBuild;
+constexpr Version APPVERSION = {1, 0};
+constexpr BuildType BUILD_TYPE = InternalBuild;
 
 #ifdef DEBUG
 # undef RELEASE
--- a/src/vertexmap.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/vertexmap.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -116,7 +116,7 @@
 	this->map.clear();
 	this->vertices.clear();
 	this->vertexHashes.clear();
-	for (int i = 0; i < this->model->size(); ++i)
+	for (std::size_t i = 0; i < this->model->size(); ++i)
 	{
 		const ModelElement& element = this->model->at(i);
 		std::optional<glm::mat4> matrix = ifplanar<glm::mat4>(
@@ -162,7 +162,7 @@
 		{
 			const std::optional<int> index = model->find(objectId);
 			if (index.has_value()) {
-				edges(this->model->at(index.value()), [&](Edge&& edge)
+				edges(this->model->at(unsigned_cast(index.value())), [&](Edge&& edge)
 				{
 					if (hashVertex(edge.a) == pair.first or hashVertex(edge.b) == pair.first)
 					{
--- a/src/widgets/matrixeditor.cpp	Wed Jun 22 16:13:15 2022 +0300
+++ b/src/widgets/matrixeditor.cpp	Wed Jun 22 16:53:35 2022 +0300
@@ -48,7 +48,7 @@
 	{
 		for (int row = 0; row < countof(this->spinboxes[0]); row += 1)
 		{
-			result[column][row] = this->spinboxes[column][row]->value();
+			result[column][row] = narrow<float>(this->spinboxes[column][row]->value());
 		}
 	}
 	return result;

mercurial