Disallow C-style arrays

This commit is contained in:
Chris Thrasher 2024-10-16 13:27:49 -06:00
parent c38b98c653
commit 18eb48b13e
40 changed files with 483 additions and 408 deletions

View File

@ -29,7 +29,6 @@ Checks: >
-clang-analyzer-osx.*, -clang-analyzer-osx.*,
-clang-analyzer-unix.Malloc, -clang-analyzer-unix.Malloc,
-clang-analyzer-unix.StdCLibraryFunctions, -clang-analyzer-unix.StdCLibraryFunctions,
-cppcoreguidelines-avoid-c-arrays,
-cppcoreguidelines-avoid-const-or-ref-data-members, -cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-avoid-do-while, -cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-magic-numbers,
@ -54,7 +53,6 @@ Checks: >
-misc-misplaced-const, -misc-misplaced-const,
-misc-no-recursion, -misc-no-recursion,
-misc-non-private-member-variables-in-classes, -misc-non-private-member-variables-in-classes,
-modernize-avoid-c-arrays,
-modernize-macro-to-enum, -modernize-macro-to-enum,
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-performance-avoid-endl, -performance-avoid-endl,

View File

@ -8,6 +8,7 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <optional> #include <optional>
#include <string_view>
#include <cstddef> #include <cstddef>
@ -34,17 +35,17 @@ void runTcpServer(unsigned short port)
std::cout << "Client connected: " << socket.getRemoteAddress().value() << std::endl; std::cout << "Client connected: " << socket.getRemoteAddress().value() << std::endl;
// Send a message to the connected client // Send a message to the connected client
const char out[] = "Hi, I'm the server"; static constexpr std::string_view out = "Hi, I'm the server";
if (socket.send(out, sizeof(out)) != sf::Socket::Status::Done) if (socket.send(out.data(), out.size()) != sf::Socket::Status::Done)
return; return;
std::cout << "Message sent to the client: " << std::quoted(out) << std::endl; std::cout << "Message sent to the client: " << std::quoted(out.data()) << std::endl;
// Receive a message back from the client // Receive a message back from the client
char in[128]; std::array<char, 128> in{};
std::size_t received = 0; std::size_t received = 0;
if (socket.receive(in, sizeof(in), received) != sf::Socket::Status::Done) if (socket.receive(in.data(), in.size(), received) != sf::Socket::Status::Done)
return; return;
std::cout << "Answer received from the client: " << std::quoted(in) << std::endl; std::cout << "Answer received from the client: " << std::quoted(in.data()) << std::endl;
} }
@ -72,15 +73,15 @@ void runTcpClient(unsigned short port)
std::cout << "Connected to server " << server.value() << std::endl; std::cout << "Connected to server " << server.value() << std::endl;
// Receive a message from the server // Receive a message from the server
char in[128]; std::array<char, 128> in{};
std::size_t received = 0; std::size_t received = 0;
if (socket.receive(in, sizeof(in), received) != sf::Socket::Status::Done) if (socket.receive(in.data(), in.size(), received) != sf::Socket::Status::Done)
return; return;
std::cout << "Message received from the server: " << std::quoted(in) << std::endl; std::cout << "Message received from the server: " << std::quoted(in.data()) << std::endl;
// Send an answer to the server // Send an answer to the server
const char out[] = "Hi, I'm a client"; static constexpr std::string_view out = "Hi, I'm a client";
if (socket.send(out, sizeof(out)) != sf::Socket::Status::Done) if (socket.send(out.data(), out.size()) != sf::Socket::Status::Done)
return; return;
std::cout << "Message sent to the server: " << std::quoted(out) << std::endl; std::cout << "Message sent to the server: " << std::quoted(out.data()) << std::endl;
} }

View File

@ -8,6 +8,7 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <optional> #include <optional>
#include <string_view>
#include <cstddef> #include <cstddef>
@ -27,19 +28,19 @@ void runUdpServer(unsigned short port)
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl; std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
// Wait for a message // Wait for a message
char in[128]; std::array<char, 128> in{};
std::size_t received = 0; std::size_t received = 0;
std::optional<sf::IpAddress> sender; std::optional<sf::IpAddress> sender;
unsigned short senderPort = 0; unsigned short senderPort = 0;
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Status::Done) if (socket.receive(in.data(), in.size(), received, sender, senderPort) != sf::Socket::Status::Done)
return; return;
std::cout << "Message received from client " << sender.value() << ": " << std::quoted(in) << std::endl; std::cout << "Message received from client " << sender.value() << ": " << std::quoted(in.data()) << std::endl;
// Send an answer to the client // Send an answer to the client
const char out[] = "Hi, I'm the server"; static constexpr std::string_view out = "Hi, I'm the server";
if (socket.send(out, sizeof(out), sender.value(), senderPort) != sf::Socket::Status::Done) if (socket.send(out.data(), out.size(), sender.value(), senderPort) != sf::Socket::Status::Done)
return; return;
std::cout << "Message sent to the client: " << std::quoted(out) << std::endl; std::cout << "Message sent to the client: " << std::quoted(out.data()) << std::endl;
} }
@ -61,17 +62,17 @@ void runUdpClient(unsigned short port)
sf::UdpSocket socket; sf::UdpSocket socket;
// Send a message to the server // Send a message to the server
const char out[] = "Hi, I'm a client"; static constexpr std::string_view out = "Hi, I'm a client";
if (socket.send(out, sizeof(out), server.value(), port) != sf::Socket::Status::Done) if (socket.send(out.data(), out.size(), server.value(), port) != sf::Socket::Status::Done)
return; return;
std::cout << "Message sent to the server: " << std::quoted(out) << std::endl; std::cout << "Message sent to the server: " << std::quoted(out.data()) << std::endl;
// Receive an answer from anyone (but most likely from the server) // Receive an answer from anyone (but most likely from the server)
char in[128]; std::array<char, 128> in{};
std::size_t received = 0; std::size_t received = 0;
std::optional<sf::IpAddress> sender; std::optional<sf::IpAddress> sender;
unsigned short senderPort = 0; unsigned short senderPort = 0;
if (socket.receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Status::Done) if (socket.receive(in.data(), in.size(), received, sender, senderPort) != sf::Socket::Status::Done)
return; return;
std::cout << "Message received from " << sender.value() << ": " << std::quoted(in) << std::endl; std::cout << "Message received from " << sender.value() << ": " << std::quoted(in.data()) << std::endl;
} }

View File

@ -6,6 +6,7 @@
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <memory> #include <memory>
@ -1018,7 +1019,7 @@ private:
{ {
public: public:
ReverbFilter(unsigned int sampleRate, float feedbackGain) : ReverbFilter(unsigned int sampleRate, float feedbackGain) :
m_allPass{{sampleRate / 10, 0.6f}, {sampleRate / 30, -0.6f}, {sampleRate / 90, 0.6f}, {sampleRate / 270, -0.6f}}, m_allPass{{{sampleRate / 10, 0.6f}, {sampleRate / 30, -0.6f}, {sampleRate / 90, 0.6f}, {sampleRate / 270, -0.6f}}},
m_fir({0.003369f, 0.002810f, 0.001758f, 0.000340f, -0.001255f, -0.002793f, -0.004014f, -0.004659f, m_fir({0.003369f, 0.002810f, 0.001758f, 0.000340f, -0.001255f, -0.002793f, -0.004014f, -0.004659f,
-0.004516f, -0.003464f, -0.001514f, 0.001148f, 0.004157f, 0.006986f, 0.009003f, 0.009571f, -0.004516f, -0.003464f, -0.001514f, 0.001148f, 0.004157f, 0.006986f, 0.009003f, 0.009571f,
0.008173f, 0.004560f, -0.001120f, -0.008222f, -0.015581f, -0.021579f, -0.024323f, -0.021933f, 0.008173f, 0.004560f, -0.001120f, -0.008222f, -0.015581f, -0.021579f, -0.024323f, -0.021933f,
@ -1052,7 +1053,7 @@ private:
} }
private: private:
AllPassFilter<T> m_allPass[4]; std::array<AllPassFilter<T>, 4> m_allPass;
FIRFilter<T> m_fir; FIRFilter<T> m_fir;
std::vector<T> m_buffer; std::vector<T> m_buffer;
std::size_t m_cursor{}; std::size_t m_cursor{};

View File

@ -26,21 +26,21 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
namespace namespace
{ {
using Matrix = float[4][4]; using Matrix = std::array<std::array<float, 4>, 4>;
// Multiply 2 matrices // Multiply 2 matrices
void matrixMultiply(Matrix& result, const Matrix& left, const Matrix& right) void matrixMultiply(Matrix& result, const Matrix& left, const Matrix& right)
{ {
Matrix temp; Matrix temp;
for (int i = 0; i < 4; ++i) for (std::size_t i = 0; i < temp.size(); ++i)
{ {
for (int j = 0; j < 4; ++j) for (std::size_t j = 0; j < temp[0].size(); ++j)
temp[i][j] = left[0][j] * right[i][0] + left[1][j] * right[i][1] + left[2][j] * right[i][2] + temp[i][j] = left[0][j] * right[i][0] + left[1][j] * right[i][1] + left[2][j] * right[i][2] +
left[3][j] * right[i][3]; left[3][j] * right[i][3];
} }
std::memcpy(result, temp, sizeof(Matrix)); result = temp;
} }
// Rotate a matrix around the x-axis // Rotate a matrix around the x-axis
@ -49,12 +49,12 @@ void matrixRotateX(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians(); const float rad = angle.asRadians();
// clang-format off // clang-format off
const Matrix matrix = { const Matrix matrix = {{
{1.f, 0.f, 0.f, 0.f}, {1.f, 0.f, 0.f, 0.f},
{0.f, std::cos(rad), std::sin(rad), 0.f}, {0.f, std::cos(rad), std::sin(rad), 0.f},
{0.f, -std::sin(rad), std::cos(rad), 0.f}, {0.f, -std::sin(rad), std::cos(rad), 0.f},
{0.f, 0.f, 0.f, 1.f} {0.f, 0.f, 0.f, 1.f}
}; }};
// clang-format on // clang-format on
matrixMultiply(result, result, matrix); matrixMultiply(result, result, matrix);
@ -66,12 +66,12 @@ void matrixRotateY(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians(); const float rad = angle.asRadians();
// clang-format off // clang-format off
const Matrix matrix = { const Matrix matrix = {{
{ std::cos(rad), 0.f, std::sin(rad), 0.f}, { std::cos(rad), 0.f, std::sin(rad), 0.f},
{ 0.f, 1.f, 0.f, 0.f}, { 0.f, 1.f, 0.f, 0.f},
{-std::sin(rad), 0.f, std::cos(rad), 0.f}, {-std::sin(rad), 0.f, std::cos(rad), 0.f},
{ 0.f, 0.f, 0.f, 1.f} { 0.f, 0.f, 0.f, 1.f}
}; }};
// clang-format on // clang-format on
matrixMultiply(result, result, matrix); matrixMultiply(result, result, matrix);
@ -83,12 +83,12 @@ void matrixRotateZ(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians(); const float rad = angle.asRadians();
// clang-format off // clang-format off
const Matrix matrix = { const Matrix matrix = {{
{ std::cos(rad), std::sin(rad), 0.f, 0.f}, { std::cos(rad), std::sin(rad), 0.f, 0.f},
{-std::sin(rad), std::cos(rad), 0.f, 0.f}, {-std::sin(rad), std::cos(rad), 0.f, 0.f},
{ 0.f, 0.f, 1.f, 0.f}, { 0.f, 0.f, 1.f, 0.f},
{ 0.f, 0.f, 0.f, 1.f} { 0.f, 0.f, 0.f, 1.f}
}; }};
// clang-format on // clang-format on
matrixMultiply(result, result, matrix); matrixMultiply(result, result, matrix);
@ -705,7 +705,7 @@ public:
deviceQueueCreateInfo.pQueuePriorities = &queuePriority; deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
// Enable the swapchain extension // Enable the swapchain extension
const char* extensions[1] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; static constexpr std::array extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
// Enable anisotropic filtering // Enable anisotropic filtering
VkPhysicalDeviceFeatures physicalDeviceFeatures = VkPhysicalDeviceFeatures(); VkPhysicalDeviceFeatures physicalDeviceFeatures = VkPhysicalDeviceFeatures();
@ -713,8 +713,8 @@ public:
VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo(); VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo();
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.enabledExtensionCount = 1; deviceCreateInfo.enabledExtensionCount = static_cast<std::uint32_t>(extensions.size());
deviceCreateInfo.ppEnabledExtensionNames = extensions; deviceCreateInfo.ppEnabledExtensionNames = extensions.data();
deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo; deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures; deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
@ -978,7 +978,7 @@ public:
// Setup renderpass and its subpass dependencies // Setup renderpass and its subpass dependencies
void setupRenderpass() void setupRenderpass()
{ {
VkAttachmentDescription attachmentDescriptions[2]; std::array<VkAttachmentDescription, 2> attachmentDescriptions{};
// Color attachment // Color attachment
attachmentDescriptions[0] = VkAttachmentDescription(); attachmentDescriptions[0] = VkAttachmentDescription();
@ -1027,8 +1027,8 @@ public:
VkRenderPassCreateInfo renderPassCreateInfo = VkRenderPassCreateInfo(); VkRenderPassCreateInfo renderPassCreateInfo = VkRenderPassCreateInfo();
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.attachmentCount = 2; renderPassCreateInfo.attachmentCount = static_cast<std::uint32_t>(attachmentDescriptions.size());
renderPassCreateInfo.pAttachments = attachmentDescriptions; renderPassCreateInfo.pAttachments = attachmentDescriptions.data();
renderPassCreateInfo.subpassCount = 1; renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpassDescription; renderPassCreateInfo.pSubpasses = &subpassDescription;
renderPassCreateInfo.dependencyCount = 1; renderPassCreateInfo.dependencyCount = 1;
@ -1045,7 +1045,7 @@ public:
// Set up uniform buffer and texture sampler descriptor set layouts // Set up uniform buffer and texture sampler descriptor set layouts
void setupDescriptorSetLayout() void setupDescriptorSetLayout()
{ {
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[2]; std::array<VkDescriptorSetLayoutBinding, 2> descriptorSetLayoutBindings{};
// Layout binding for uniform buffer // Layout binding for uniform buffer
descriptorSetLayoutBindings[0] = VkDescriptorSetLayoutBinding(); descriptorSetLayoutBindings[0] = VkDescriptorSetLayoutBinding();
@ -1063,8 +1063,8 @@ public:
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = VkDescriptorSetLayoutCreateInfo(); VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = VkDescriptorSetLayoutCreateInfo();
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.bindingCount = 2; descriptorSetLayoutCreateInfo.bindingCount = static_cast<std::uint32_t>(descriptorSetLayoutBindings.size());
descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings; descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings.data();
// Create descriptor set layout // Create descriptor set layout
if (vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) if (vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
@ -1100,7 +1100,7 @@ public:
vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
// Set up how the vertex buffer data is interpreted as attributes by the vertex shader // Set up how the vertex buffer data is interpreted as attributes by the vertex shader
VkVertexInputAttributeDescription vertexInputAttributeDescriptions[3]; std::array<VkVertexInputAttributeDescription, 3> vertexInputAttributeDescriptions{};
// Position attribute // Position attribute
vertexInputAttributeDescriptions[0] = VkVertexInputAttributeDescription(); vertexInputAttributeDescriptions[0] = VkVertexInputAttributeDescription();
@ -1127,8 +1127,9 @@ public:
vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1; vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription; vertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 3; vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(
vertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions; vertexInputAttributeDescriptions.size());
vertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions.data();
// We want to generate a triangle list with our vertex data // We want to generate a triangle list with our vertex data
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo(); VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo();
@ -1204,8 +1205,8 @@ public:
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = VkGraphicsPipelineCreateInfo(); VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = VkGraphicsPipelineCreateInfo();
graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
graphicsPipelineCreateInfo.stageCount = 2; graphicsPipelineCreateInfo.stageCount = static_cast<std::uint32_t>(shaderStages.size());
graphicsPipelineCreateInfo.pStages = shaderStages; graphicsPipelineCreateInfo.pStages = shaderStages.data();
graphicsPipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo; graphicsPipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo;
graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo; graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo;
graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo; graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo;
@ -1242,9 +1243,9 @@ public:
for (std::size_t i = 0; i < swapchainFramebuffers.size(); ++i) for (std::size_t i = 0; i < swapchainFramebuffers.size(); ++i)
{ {
// Each framebuffer consists of a corresponding swapchain image and the shared depth image // Each framebuffer consists of a corresponding swapchain image and the shared depth image
VkImageView attachments[] = {swapchainImageViews[i], depthImageView}; const std::array attachments = {swapchainImageViews[i], depthImageView};
framebufferCreateInfo.pAttachments = attachments; framebufferCreateInfo.pAttachments = attachments.data();
// Create the framebuffer // Create the framebuffer
if (vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &swapchainFramebuffers[i]) != VK_SUCCESS) if (vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &swapchainFramebuffers[i]) != VK_SUCCESS)
@ -2130,7 +2131,7 @@ public:
void setupDescriptorPool() void setupDescriptorPool()
{ {
// We need to allocate as many descriptor sets as we have frames in flight // We need to allocate as many descriptor sets as we have frames in flight
VkDescriptorPoolSize descriptorPoolSizes[2]; std::array<VkDescriptorPoolSize, 2> descriptorPoolSizes{};
descriptorPoolSizes[0] = VkDescriptorPoolSize(); descriptorPoolSizes[0] = VkDescriptorPoolSize();
descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@ -2142,8 +2143,8 @@ public:
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = VkDescriptorPoolCreateInfo(); VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = VkDescriptorPoolCreateInfo();
descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCreateInfo.poolSizeCount = 2; descriptorPoolCreateInfo.poolSizeCount = static_cast<std::uint32_t>(descriptorPoolSizes.size());
descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes.data();
descriptorPoolCreateInfo.maxSets = static_cast<std::uint32_t>(swapchainImages.size()); descriptorPoolCreateInfo.maxSets = static_cast<std::uint32_t>(swapchainImages.size());
// Create the descriptor pool // Create the descriptor pool
@ -2179,7 +2180,7 @@ public:
// For every descriptor set, set up the bindings to our uniform buffer and texture sampler // For every descriptor set, set up the bindings to our uniform buffer and texture sampler
for (std::size_t i = 0; i < descriptorSets.size(); ++i) for (std::size_t i = 0; i < descriptorSets.size(); ++i)
{ {
VkWriteDescriptorSet writeDescriptorSets[2]; std::array<VkWriteDescriptorSet, 2> writeDescriptorSets{};
// Uniform buffer binding information // Uniform buffer binding information
VkDescriptorBufferInfo descriptorBufferInfo = VkDescriptorBufferInfo(); VkDescriptorBufferInfo descriptorBufferInfo = VkDescriptorBufferInfo();
@ -2212,7 +2213,11 @@ public:
writeDescriptorSets[1].pImageInfo = &descriptorImageInfo; writeDescriptorSets[1].pImageInfo = &descriptorImageInfo;
// Update the descriptor set // Update the descriptor set
vkUpdateDescriptorSets(device, 2, writeDescriptorSets, 0, nullptr); vkUpdateDescriptorSets(device,
static_cast<std::uint32_t>(writeDescriptorSets.size()),
writeDescriptorSets.data(),
0,
nullptr);
} }
} }
@ -2242,7 +2247,7 @@ public:
void setupDraw() void setupDraw()
{ {
// Set up our clear colors // Set up our clear colors
VkClearValue clearColors[2]; std::array<VkClearValue, 2> clearColors{};
// Clear color buffer to opaque black // Clear color buffer to opaque black
clearColors[0] = VkClearValue(); clearColors[0] = VkClearValue();
@ -2262,8 +2267,8 @@ public:
renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent = swapchainExtent; renderPassBeginInfo.renderArea.extent = swapchainExtent;
renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.clearValueCount = static_cast<std::uint32_t>(clearColors.size());
renderPassBeginInfo.pClearValues = clearColors; renderPassBeginInfo.pClearValues = clearColors.data();
// Simultaneous use: this command buffer can be resubmitted to a queue before a previous submission is completed // Simultaneous use: this command buffer can be resubmitted to a queue before a previous submission is completed
VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo(); VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
@ -2380,7 +2385,14 @@ public:
void updateUniformBuffer(float elapsed) void updateUniformBuffer(float elapsed)
{ {
// Construct the model matrix // Construct the model matrix
Matrix model = {{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}; // clang-format off
Matrix model = {{
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}
}};
// clang-format on
matrixRotateX(model, sf::degrees(elapsed * 59.0f)); matrixRotateX(model, sf::degrees(elapsed * 59.0f));
matrixRotateY(model, sf::degrees(elapsed * 83.0f)); matrixRotateY(model, sf::degrees(elapsed * 83.0f));
@ -2424,9 +2436,9 @@ public:
} }
// Copy the matrix data into the current frame's uniform buffer // Copy the matrix data into the current frame's uniform buffer
std::memcpy(ptr + sizeof(Matrix) * 0, model, sizeof(Matrix)); std::memcpy(ptr + sizeof(Matrix) * 0, model.data(), sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 1, view, sizeof(Matrix)); std::memcpy(ptr + sizeof(Matrix) * 1, view.data(), sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 2, projection, sizeof(Matrix)); std::memcpy(ptr + sizeof(Matrix) * 2, projection.data(), sizeof(Matrix));
// Unmap the buffer // Unmap the buffer
vkUnmapMemory(device, uniformBuffersMemory[currentFrame]); vkUnmapMemory(device, uniformBuffersMemory[currentFrame]);
@ -2579,7 +2591,7 @@ private:
VkImageView depthImageView{}; VkImageView depthImageView{};
VkShaderModule vertexShaderModule{}; VkShaderModule vertexShaderModule{};
VkShaderModule fragmentShaderModule{}; VkShaderModule fragmentShaderModule{};
VkPipelineShaderStageCreateInfo shaderStages[2]{}; std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages{};
VkDescriptorSetLayout descriptorSetLayout{}; VkDescriptorSetLayout descriptorSetLayout{};
VkPipelineLayout pipelineLayout{}; VkPipelineLayout pipelineLayout{};
VkRenderPass renderPass{}; VkRenderPass renderPass{};

View File

@ -319,11 +319,11 @@ private:
/// << "sample count: " << file.getSampleCount() << std::endl; /// << "sample count: " << file.getSampleCount() << std::endl;
/// ///
/// // Read and process batches of samples until the end of file is reached /// // Read and process batches of samples until the end of file is reached
/// std::int16_t samples[1024]; /// std::array<std::int16_t, 1024> samples;
/// std::uint64_t count; /// std::uint64_t count;
/// do /// do
/// { /// {
/// count = file.read(samples, 1024); /// count = file.read(samples.data(), samples.size());
/// ///
/// // process, analyze, play, convert, or whatever /// // process, analyze, play, convert, or whatever
/// // you want to do with the samples... /// // you want to do with the samples...

View File

@ -30,6 +30,8 @@
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/Glsl.hpp> // NOLINT(misc-header-include-cycle) #include <SFML/Graphics/Glsl.hpp> // NOLINT(misc-header-include-cycle)
#include <array>
#include <cstddef> #include <cstddef>
@ -74,7 +76,7 @@ struct Matrix
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
explicit Matrix(const float* pointer) explicit Matrix(const float* pointer)
{ {
copyMatrix(pointer, Columns * Rows, array); copyMatrix(pointer, Columns * Rows, array.data());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -91,7 +93,7 @@ struct Matrix
copyMatrix(transform, *this); copyMatrix(transform, *this);
} }
float array[Columns * Rows]{}; //!< Array holding matrix data std::array<float, Columns * Rows> array{}; //!< Array holding matrix data
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -400,11 +400,11 @@ SFML_GRAPHICS_API void swap(VertexBuffer& left, VertexBuffer& right) noexcept;
/// ///
/// Example: /// Example:
/// \code /// \code
/// sf::Vertex vertices[15]; /// std::array<sf::Vertex, 15> vertices;
/// ... /// ...
/// sf::VertexBuffer triangles(sf::PrimitiveType::Triangles); /// sf::VertexBuffer triangles(sf::PrimitiveType::Triangles);
/// triangles.create(15); /// triangles.create(vertices.size());
/// triangles.update(vertices); /// triangles.update(vertices.data());
/// ... /// ...
/// window.draw(triangles); /// window.draw(triangles);
/// \endcode /// \endcode

View File

@ -285,10 +285,10 @@ private:
/// socket.send(message.c_str(), message.size() + 1); /// socket.send(message.c_str(), message.size() + 1);
/// ///
/// // Receive an answer from the server /// // Receive an answer from the server
/// char buffer[1024]; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// socket.receive(buffer, sizeof(buffer), received); /// socket.receive(buffer.data(), buffer.size(), received);
/// std::cout << "The server said: " << buffer << std::endl; /// std::cout << "The server said: " << buffer.data() << std::endl;
/// ///
/// // ----- The server ----- /// // ----- The server -----
/// ///
@ -302,10 +302,10 @@ private:
/// std::cout << "New client connected: " << socket.getRemoteAddress().value() << std::endl; /// std::cout << "New client connected: " << socket.getRemoteAddress().value() << std::endl;
/// ///
/// // Receive a message from the client /// // Receive a message from the client
/// char buffer[1024]; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// socket.receive(buffer, sizeof(buffer), received); /// socket.receive(buffer.data(), buffer.size(), received);
/// std::cout << "The client said: " << buffer << std::endl; /// std::cout << "The client said: " << buffer.data() << std::endl;
/// ///
/// // Send an answer /// // Send an answer
/// std::string message = "Welcome, client"; /// std::string message = "Welcome, client";

View File

@ -262,12 +262,12 @@ private:
/// socket.send(message.c_str(), message.size() + 1, "192.168.1.50", 55002); /// socket.send(message.c_str(), message.size() + 1, "192.168.1.50", 55002);
/// ///
/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else) /// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
/// char buffer[1024]; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// std::optional<sf::IpAddress> sender; /// std::optional<sf::IpAddress> sender;
/// unsigned short port; /// unsigned short port;
/// if (socket.receive(buffer, sizeof(buffer), received, sender, port) == sf::Socket::Status::Done) /// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer << std::endl; /// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
/// ///
/// // ----- The server ----- /// // ----- The server -----
/// ///
@ -276,12 +276,12 @@ private:
/// socket.bind(55002); /// socket.bind(55002);
/// ///
/// // Receive a message from anyone /// // Receive a message from anyone
/// char buffer[1024]; /// std::array<char, 1024> buffer;
/// std::size_t received = 0; /// std::size_t received = 0;
/// std::optional<sf::IpAddress> sender; /// std::optional<sf::IpAddress> sender;
/// unsigned short port; /// unsigned short port;
/// if (socket.receive(buffer, sizeof(buffer), received, sender, port) == sf::Socket::Status::Done) /// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer << std::endl; /// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
/// ///
/// // Send an answer /// // Send an answer
/// std::string message = "Welcome " + sender.toString(); /// std::string message = "Welcome " + sender.toString();

View File

@ -40,7 +40,11 @@
namespace namespace
{ {
FLAC__StreamDecoderReadStatus streamRead(const FLAC__StreamDecoder*, FLAC__byte buffer[], std::size_t* bytes, void* clientData) FLAC__StreamDecoderReadStatus streamRead(
const FLAC__StreamDecoder*,
FLAC__byte buffer[], // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
std::size_t* bytes,
void* clientData)
{ {
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData); auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
@ -101,10 +105,13 @@ FLAC__bool streamEof(const FLAC__StreamDecoder*, void* clientData)
return data->stream->tell() == data->stream->getSize(); return data->stream->tell() == data->stream->getSize();
} }
FLAC__StreamDecoderWriteStatus streamWrite(const FLAC__StreamDecoder*,
FLAC__StreamDecoderWriteStatus streamWrite(
const FLAC__StreamDecoder*,
const FLAC__Frame* frame, const FLAC__Frame* frame,
const FLAC__int32* const buffer[], const FLAC__int32* const buffer[], // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
void* clientData) void* clientData)
{ {
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData); auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);

View File

@ -56,6 +56,7 @@
#include <SFML/System/InputStream.hpp> #include <SFML/System/InputStream.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <ostream> #include <ostream>
#include <cassert> #include <cassert>
@ -90,15 +91,15 @@ namespace sf::priv
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool SoundFileReaderMp3::check(InputStream& stream) bool SoundFileReaderMp3::check(InputStream& stream)
{ {
std::uint8_t header[10]; std::array<std::uint8_t, 10> header{};
if (stream.read(header, sizeof(header)) != sizeof(header)) if (stream.read(header.data(), header.size()) != header.size())
return false; return false;
if (hasValidId3Tag(header)) if (hasValidId3Tag(header.data()))
return true; return true;
if (hdr_valid(header)) if (hdr_valid(header.data()))
return true; return true;
return false; return false;

View File

@ -30,6 +30,7 @@
#include <SFML/Audio/SoundFileWriter.hpp> #include <SFML/Audio/SoundFileWriter.hpp>
#include <FLAC/stream_encoder.h> #include <FLAC/stream_encoder.h>
#include <array>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -91,7 +92,7 @@ private:
}; };
std::unique_ptr<FLAC__StreamEncoder, FlacStreamEncoderDeleter> m_encoder; //!< FLAC stream encoder std::unique_ptr<FLAC__StreamEncoder, FlacStreamEncoderDeleter> m_encoder; //!< FLAC stream encoder
unsigned int m_channelCount{}; //!< Number of channels unsigned int m_channelCount{}; //!< Number of channels
std::size_t m_remapTable[8]{}; //!< Table we use to remap source to target channel order std::array<std::size_t, 8> m_remapTable{}; //!< Table we use to remap source to target channel order
std::vector<std::int32_t> m_samples32; //!< Conversion buffer std::vector<std::int32_t> m_samples32; //!< Conversion buffer
}; };

View File

@ -247,16 +247,16 @@ void SoundFileWriterWav::writeHeader(unsigned int sampleRate, unsigned int chann
assert(m_file.good() && "Most recent I/O operation failed"); assert(m_file.good() && "Most recent I/O operation failed");
// Write the main chunk ID // Write the main chunk ID
std::array mainChunkId = {'R', 'I', 'F', 'F'}; static constexpr std::array mainChunkId = {'R', 'I', 'F', 'F'};
m_file.write(mainChunkId.data(), mainChunkId.size()); m_file.write(mainChunkId.data(), mainChunkId.size());
// Write the main chunk header // Write the main chunk header
encode(m_file, std::uint32_t{0}); // 0 is a placeholder, will be written later encode(m_file, std::uint32_t{0}); // 0 is a placeholder, will be written later
std::array mainChunkFormat = {'W', 'A', 'V', 'E'}; static constexpr std::array mainChunkFormat = {'W', 'A', 'V', 'E'};
m_file.write(mainChunkFormat.data(), mainChunkFormat.size()); m_file.write(mainChunkFormat.data(), mainChunkFormat.size());
// Write the sub-chunk 1 ("format") id and size // Write the sub-chunk 1 ("format") id and size
std::array fmtChunkId = {'f', 'm', 't', ' '}; static constexpr std::array fmtChunkId = {'f', 'm', 't', ' '};
m_file.write(fmtChunkId.data(), fmtChunkId.size()); m_file.write(fmtChunkId.data(), fmtChunkId.size());
if (channelCount > 2) if (channelCount > 2)
@ -295,13 +295,13 @@ void SoundFileWriterWav::writeHeader(unsigned int sampleRate, unsigned int chann
encode(m_file, bitsPerSample); encode(m_file, bitsPerSample);
encode(m_file, channelMask); encode(m_file, channelMask);
// Write the subformat (PCM) // Write the subformat (PCM)
std::array subformat = static constexpr std::array subformat =
{'\x01', '\x00', '\x00', '\x00', '\x00', '\x00', '\x10', '\x00', '\x80', '\x00', '\x00', '\xAA', '\x00', '\x38', '\x9B', '\x71'}; {'\x01', '\x00', '\x00', '\x00', '\x00', '\x00', '\x10', '\x00', '\x80', '\x00', '\x00', '\xAA', '\x00', '\x38', '\x9B', '\x71'};
m_file.write(subformat.data(), subformat.size()); m_file.write(subformat.data(), subformat.size());
} }
// Write the sub-chunk 2 ("data") id and size // Write the sub-chunk 2 ("data") id and size
std::array dataChunkId = {'d', 'a', 't', 'a'}; static constexpr std::array dataChunkId = {'d', 'a', 't', 'a'};
m_file.write(dataChunkId.data(), dataChunkId.size()); m_file.write(dataChunkId.data(), dataChunkId.size());
const std::uint32_t dataChunkSize = 0; // placeholder, will be written later const std::uint32_t dataChunkSize = 0; // placeholder, will be written later
encode(m_file, dataChunkSize); encode(m_file, dataChunkSize);

View File

@ -40,7 +40,7 @@ namespace sf::priv
void copyMatrix(const Transform& source, Matrix<3, 3>& dest) void copyMatrix(const Transform& source, Matrix<3, 3>& dest)
{ {
const float* from = source.getMatrix(); // 4x4 const float* from = source.getMatrix(); // 4x4
float* to = dest.array; // 3x3 auto& to = dest.array; // 3x3
// Use only left-upper 3x3 block (for a 2D transform) // Use only left-upper 3x3 block (for a 2D transform)
to[0] = from[0]; to[0] = from[0];
@ -59,7 +59,7 @@ void copyMatrix(const Transform& source, Matrix<3, 3>& dest)
void copyMatrix(const Transform& source, Matrix<4, 4>& dest) void copyMatrix(const Transform& source, Matrix<4, 4>& dest)
{ {
// Adopt 4x4 matrix as-is // Adopt 4x4 matrix as-is
copyMatrix(source.getMatrix(), 4 * 4, dest.array); copyMatrix(source.getMatrix(), dest.array.size(), dest.array.data());
} }

View File

@ -35,6 +35,7 @@
#include <SFML/Window/Context.hpp> #include <SFML/Window/Context.hpp>
#include <SFML/System/EnumArray.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm> #include <algorithm>
@ -889,8 +890,9 @@ void RenderTarget::setupDraw(bool useVertexCache, const RenderStates& states)
void RenderTarget::drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount) void RenderTarget::drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount)
{ {
// Find the OpenGL primitive type // Find the OpenGL primitive type
static constexpr GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN}; static constexpr priv::EnumArray<PrimitiveType, GLenum, 6> modes =
const GLenum mode = modes[static_cast<std::size_t>(type)]; {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN};
const GLenum mode = modes[type];
// Draw the primitives // Draw the primitives
glCheck(glDrawArrays(mode, static_cast<GLint>(firstVertex), static_cast<GLsizei>(vertexCount))); glCheck(glDrawArrays(mode, static_cast<GLint>(firstVertex), static_cast<GLsizei>(vertexCount)));

View File

@ -635,7 +635,7 @@ void Shader::setUniform(const std::string& name, const Glsl::Mat3& matrix)
{ {
const UniformBinder binder(*this, name); const UniformBinder binder(*this, name);
if (binder.location != -1) if (binder.location != -1)
glCheck(GLEXT_glUniformMatrix3fv(binder.location, 1, GL_FALSE, matrix.array)); glCheck(GLEXT_glUniformMatrix3fv(binder.location, 1, GL_FALSE, matrix.array.data()));
} }
@ -644,7 +644,7 @@ void Shader::setUniform(const std::string& name, const Glsl::Mat4& matrix)
{ {
const UniformBinder binder(*this, name); const UniformBinder binder(*this, name);
if (binder.location != -1) if (binder.location != -1)
glCheck(GLEXT_glUniformMatrix4fv(binder.location, 1, GL_FALSE, matrix.array)); glCheck(GLEXT_glUniformMatrix4fv(binder.location, 1, GL_FALSE, matrix.array.data()));
} }
@ -741,11 +741,11 @@ void Shader::setUniformArray(const std::string& name, const Glsl::Vec4* vectorAr
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shader::setUniformArray(const std::string& name, const Glsl::Mat3* matrixArray, std::size_t length) void Shader::setUniformArray(const std::string& name, const Glsl::Mat3* matrixArray, std::size_t length)
{ {
const std::size_t matrixSize = 3 * 3; static const std::size_t matrixSize = matrixArray[0].array.size();
std::vector<float> contiguous(matrixSize * length); std::vector<float> contiguous(matrixSize * length);
for (std::size_t i = 0; i < length; ++i) for (std::size_t i = 0; i < length; ++i)
priv::copyMatrix(matrixArray[i].array, matrixSize, &contiguous[matrixSize * i]); priv::copyMatrix(matrixArray[i].array.data(), matrixSize, &contiguous[matrixSize * i]);
const UniformBinder binder(*this, name); const UniformBinder binder(*this, name);
if (binder.location != -1) if (binder.location != -1)
@ -756,11 +756,11 @@ void Shader::setUniformArray(const std::string& name, const Glsl::Mat3* matrixAr
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shader::setUniformArray(const std::string& name, const Glsl::Mat4* matrixArray, std::size_t length) void Shader::setUniformArray(const std::string& name, const Glsl::Mat4* matrixArray, std::size_t length)
{ {
const std::size_t matrixSize = 4 * 4; static const std::size_t matrixSize = matrixArray[0].array.size();
std::vector<float> contiguous(matrixSize * length); std::vector<float> contiguous(matrixSize * length);
for (std::size_t i = 0; i < length; ++i) for (std::size_t i = 0; i < length; ++i)
priv::copyMatrix(matrixArray[i].array, matrixSize, &contiguous[matrixSize * i]); priv::copyMatrix(matrixArray[i].array.data(), matrixSize, &contiguous[matrixSize * i]);
const UniformBinder binder(*this, name); const UniformBinder binder(*this, name);
if (binder.location != -1) if (binder.location != -1)
@ -884,7 +884,7 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
if (success == GL_FALSE) if (success == GL_FALSE)
{ {
std::array<char, 1024> log{}; std::array<char, 1024> log{};
glCheck(GLEXT_glGetInfoLog(shader, sizeof(log), nullptr, log.data())); glCheck(GLEXT_glGetInfoLog(shader, static_cast<GLsizei>(log.size()), nullptr, log.data()));
err() << "Failed to compile " << shaderTypeStr << " shader:" << '\n' << log.data() << std::endl; err() << "Failed to compile " << shaderTypeStr << " shader:" << '\n' << log.data() << std::endl;
glCheck(GLEXT_glDeleteObject(shader)); glCheck(GLEXT_glDeleteObject(shader));
glCheck(GLEXT_glDeleteObject(shaderProgram)); glCheck(GLEXT_glDeleteObject(shaderProgram));
@ -921,7 +921,7 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
if (success == GL_FALSE) if (success == GL_FALSE)
{ {
std::array<char, 1024> log{}; std::array<char, 1024> log{};
glCheck(GLEXT_glGetInfoLog(shaderProgram, sizeof(log), nullptr, log.data())); glCheck(GLEXT_glGetInfoLog(shaderProgram, static_cast<GLsizei>(log.size()), nullptr, log.data()));
err() << "Failed to link shader:" << '\n' << log.data() << std::endl; err() << "Failed to link shader:" << '\n' << log.data() << std::endl;
glCheck(GLEXT_glDeleteObject(shaderProgram)); glCheck(GLEXT_glDeleteObject(shaderProgram));
return false; return false;

View File

@ -31,6 +31,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <fstream> #include <fstream>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
@ -381,23 +382,23 @@ Ftp::Response Ftp::getResponse()
for (;;) for (;;)
{ {
// Receive the response from the server // Receive the response from the server
char buffer[1024]; std::array<char, 1024> buffer{};
std::size_t length = 0; std::size_t length = 0;
if (m_receiveBuffer.empty()) if (m_receiveBuffer.empty())
{ {
if (m_commandSocket.receive(buffer, sizeof(buffer), length) != Socket::Status::Done) if (m_commandSocket.receive(buffer.data(), buffer.size(), length) != Socket::Status::Done)
return Response(Response::Status::ConnectionClosed); return Response(Response::Status::ConnectionClosed);
} }
else else
{ {
std::copy(m_receiveBuffer.begin(), m_receiveBuffer.end(), buffer); std::copy(m_receiveBuffer.begin(), m_receiveBuffer.end(), buffer.data());
length = m_receiveBuffer.size(); length = m_receiveBuffer.size();
m_receiveBuffer.clear(); m_receiveBuffer.clear();
} }
// There can be several lines inside the received buffer, extract them all // There can be several lines inside the received buffer, extract them all
std::istringstream in(std::string(buffer, length), std::ios_base::binary); std::istringstream in(std::string(buffer.data(), length), std::ios_base::binary);
while (in) while (in)
{ {
// Try to extract the code // Try to extract the code
@ -451,7 +452,7 @@ Ftp::Response Ftp::getResponse()
} }
// Save the remaining data for the next time getResponse() is called // Save the remaining data for the next time getResponse() is called
m_receiveBuffer.assign(buffer + static_cast<std::size_t>(in.tellg()), m_receiveBuffer.assign(buffer.data() + static_cast<std::size_t>(in.tellg()),
length - static_cast<std::size_t>(in.tellg())); length - static_cast<std::size_t>(in.tellg()));
// Return the response code and message // Return the response code and message
@ -526,7 +527,7 @@ Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode)
const std::string::size_type begin = response.getMessage().find_first_of("0123456789"); const std::string::size_type begin = response.getMessage().find_first_of("0123456789");
if (begin != std::string::npos) if (begin != std::string::npos)
{ {
std::uint8_t data[6] = {0, 0, 0, 0, 0, 0}; std::array<std::uint8_t, 6> data{};
std::string str = response.getMessage().substr(begin); std::string str = response.getMessage().substr(begin);
std::size_t index = 0; std::size_t index = 0;
for (unsigned char& datum : data) for (unsigned char& datum : data)
@ -584,11 +585,11 @@ Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode)
void Ftp::DataChannel::receive(std::ostream& stream) void Ftp::DataChannel::receive(std::ostream& stream)
{ {
// Receive data // Receive data
char buffer[1024]; std::array<char, 1024> buffer{};
std::size_t received = 0; std::size_t received = 0;
while (m_dataSocket.receive(buffer, sizeof(buffer), received) == Socket::Status::Done) while (m_dataSocket.receive(buffer.data(), buffer.size(), received) == Socket::Status::Done)
{ {
stream.write(buffer, static_cast<std::streamsize>(received)); stream.write(buffer.data(), static_cast<std::streamsize>(received));
if (!stream.good()) if (!stream.good())
{ {
@ -606,13 +607,13 @@ void Ftp::DataChannel::receive(std::ostream& stream)
void Ftp::DataChannel::send(std::istream& stream) void Ftp::DataChannel::send(std::istream& stream)
{ {
// Send data // Send data
char buffer[1024]; std::array<char, 1024> buffer{};
std::size_t count = 0; std::size_t count = 0;
for (;;) for (;;)
{ {
// read some data from the stream // read some data from the stream
stream.read(buffer, sizeof(buffer)); stream.read(buffer.data(), buffer.size());
if (!stream.good() && !stream.eof()) if (!stream.good() && !stream.eof())
{ {
@ -625,7 +626,7 @@ void Ftp::DataChannel::send(std::istream& stream)
if (count > 0) if (count > 0)
{ {
// we could read more data from the stream: send them // we could read more data from the stream: send them
if (m_dataSocket.send(buffer, count) != Socket::Status::Done) if (m_dataSocket.send(buffer.data(), count) != Socket::Status::Done)
break; break;
} }
else else

View File

@ -31,6 +31,7 @@
#include <SFML/System/Utils.hpp> #include <SFML/System/Utils.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#include <ostream> #include <ostream>
@ -377,10 +378,10 @@ Http::Response Http::sendRequest(const Http::Request& request, Time timeout)
// Wait for the server's response // Wait for the server's response
std::string receivedStr; std::string receivedStr;
std::size_t size = 0; std::size_t size = 0;
char buffer[1024]; std::array<char, 1024> buffer{};
while (m_connection.receive(buffer, sizeof(buffer), size) == Socket::Status::Done) while (m_connection.receive(buffer.data(), buffer.size(), size) == Socket::Status::Done)
{ {
receivedStr.append(buffer, buffer + size); receivedStr.append(buffer.data(), buffer.data() + size);
} }
// Build the Response object from the received data // Build the Response object from the received data

View File

@ -196,8 +196,8 @@ Packet& Packet::operator>>(std::int64_t& data)
{ {
// Since ntohll is not available everywhere, we have to convert // Since ntohll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
std::byte bytes[sizeof(data)]; std::array<std::byte, sizeof(data)> bytes{};
std::memcpy(bytes, &m_data[m_readPos], sizeof(data)); std::memcpy(bytes.data(), &m_data[m_readPos], bytes.size());
data = toInteger<std::int64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]); data = toInteger<std::int64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]);
@ -434,7 +434,7 @@ Packet& Packet::operator<<(std::int64_t data)
// Since htonll is not available everywhere, we have to convert // Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF), const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
static_cast<std::uint8_t>((data >> 48) & 0xFF), static_cast<std::uint8_t>((data >> 48) & 0xFF),
static_cast<std::uint8_t>((data >> 40) & 0xFF), static_cast<std::uint8_t>((data >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF), static_cast<std::uint8_t>((data >> 32) & 0xFF),
@ -443,7 +443,7 @@ Packet& Packet::operator<<(std::int64_t data)
static_cast<std::uint8_t>((data >> 8) & 0xFF), static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 0xFF)}; static_cast<std::uint8_t>((data) & 0xFF)};
append(&toWrite, sizeof(toWrite)); append(toWrite.data(), toWrite.size());
return *this; return *this;
} }
@ -454,7 +454,7 @@ Packet& Packet::operator<<(std::uint64_t data)
// Since htonll is not available everywhere, we have to convert // Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually // to network byte order (big endian) manually
std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF), const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
static_cast<std::uint8_t>((data >> 48) & 0xFF), static_cast<std::uint8_t>((data >> 48) & 0xFF),
static_cast<std::uint8_t>((data >> 40) & 0xFF), static_cast<std::uint8_t>((data >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF), static_cast<std::uint8_t>((data >> 32) & 0xFF),
@ -463,7 +463,7 @@ Packet& Packet::operator<<(std::uint64_t data)
static_cast<std::uint8_t>((data >> 8) & 0xFF), static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 0xFF)}; static_cast<std::uint8_t>((data) & 0xFF)};
append(&toWrite, sizeof(toWrite)); append(toWrite.data(), toWrite.size());
return *this; return *this;
} }

View File

@ -402,7 +402,7 @@ Socket::Status TcpSocket::receive(Packet& packet)
while (m_pendingPacket.data.size() < packetSize) while (m_pendingPacket.data.size() < packetSize)
{ {
// Receive a chunk of data // Receive a chunk of data
const std::size_t sizeToGet = std::min(packetSize - m_pendingPacket.data.size(), sizeof(buffer)); const std::size_t sizeToGet = std::min(packetSize - m_pendingPacket.data.size(), buffer.size());
const Status status = receive(buffer.data(), sizeToGet, received); const Status status = receive(buffer.data(), sizeToGet, received);
if (status != Status::Done) if (status != Status::Done)
return status; return status;

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <SFML/System/Sleep.hpp> #include <SFML/System/Sleep.hpp>
#include <array>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <unistd.h> #include <unistd.h>
@ -159,18 +160,18 @@ DrmFb* drmFbGetFromBo(gbm_bo& bo)
const std::uint32_t height = gbm_bo_get_height(&bo); const std::uint32_t height = gbm_bo_get_height(&bo);
const std::uint32_t format = gbm_bo_get_format(&bo); const std::uint32_t format = gbm_bo_get_format(&bo);
std::uint32_t strides[4] = {0}; std::array<std::uint32_t, 4> strides{};
std::uint32_t handles[4] = {0}; std::array<std::uint32_t, 4> handles{};
std::uint32_t offsets[4] = {0}; std::array<std::uint32_t, 4> offsets{};
std::uint64_t modifiers[4] = {0}; std::array<std::uint64_t, 4> modifiers{};
modifiers[0] = gbm_bo_get_modifier(&bo); modifiers[0] = gbm_bo_get_modifier(&bo);
const int numPlanes = gbm_bo_get_plane_count(&bo); const int numPlanes = gbm_bo_get_plane_count(&bo);
for (int i = 0; i < numPlanes; ++i) for (int i = 0; i < numPlanes; ++i)
{ {
strides[i] = gbm_bo_get_stride_for_plane(&bo, i); strides[static_cast<std::size_t>(i)] = gbm_bo_get_stride_for_plane(&bo, i);
handles[i] = gbm_bo_get_handle(&bo).u32; handles[static_cast<std::size_t>(i)] = gbm_bo_get_handle(&bo).u32;
offsets[i] = gbm_bo_get_offset(&bo, i); offsets[static_cast<std::size_t>(i)] = gbm_bo_get_offset(&bo, i);
modifiers[i] = modifiers[0]; modifiers[static_cast<std::size_t>(i)] = modifiers[0];
} }
std::uint32_t flags = 0; std::uint32_t flags = 0;
@ -179,16 +180,25 @@ DrmFb* drmFbGetFromBo(gbm_bo& bo)
flags = DRM_MODE_FB_MODIFIERS; flags = DRM_MODE_FB_MODIFIERS;
} }
int result = drmModeAddFB2WithModifiers(drmFd, width, height, format, handles, strides, offsets, modifiers, &fb->fbId, flags); int result = drmModeAddFB2WithModifiers(drmFd,
width,
height,
format,
handles.data(),
strides.data(),
offsets.data(),
modifiers.data(),
&fb->fbId,
flags);
if (result) if (result)
{ {
std::memset(handles, 0, 16); handles.fill(0);
handles[0] = gbm_bo_get_handle(&bo).u32; handles[0] = gbm_bo_get_handle(&bo).u32;
std::memset(strides, 0, 16); strides.fill(0);
strides[0] = gbm_bo_get_stride(&bo); strides[0] = gbm_bo_get_stride(&bo);
std::memset(offsets, 0, 16); offsets.fill(0);
result = drmModeAddFB2(drmFd, width, height, format, handles, strides, offsets, &fb->fbId, 0); result = drmModeAddFB2(drmFd, width, height, format, handles.data(), strides.data(), offsets.data(), &fb->fbId, 0);
} }
if (result) if (result)
@ -271,11 +281,9 @@ int hasMonitorConnected(int fd, drmModeRes& resources)
int findDrmDevice(drmModeResPtr& resources) int findDrmDevice(drmModeResPtr& resources)
{ {
static const int maxDrmDevices = 64; std::array<drmDevicePtr, 64> devices{};
drmDevicePtr devices[maxDrmDevices] = {}; const int numDevices = drmGetDevices2(0, devices.data(), devices.size());
const int numDevices = drmGetDevices2(0, devices, maxDrmDevices);
if (numDevices < 0) if (numDevices < 0)
{ {
sf::err() << "drmGetDevices2 failed: " << std::strerror(-numDevices) << std::endl; sf::err() << "drmGetDevices2 failed: " << std::strerror(-numDevices) << std::endl;
@ -283,7 +291,7 @@ int findDrmDevice(drmModeResPtr& resources)
} }
int fileDescriptor = -1; int fileDescriptor = -1;
for (int i = 0; i < numDevices; ++i) for (std::size_t i = 0; i < static_cast<std::size_t>(numDevices); ++i)
{ {
drmDevicePtr device = devices[i]; drmDevicePtr device = devices[i];
int result = 0; int result = 0;
@ -303,7 +311,7 @@ int findDrmDevice(drmModeResPtr& resources)
close(fileDescriptor); close(fileDescriptor);
fileDescriptor = -1; fileDescriptor = -1;
} }
drmFreeDevices(devices, numDevices); drmFreeDevices(devices.data(), numDevices);
if (fileDescriptor < 0) if (fileDescriptor < 0)
sf::err() << "No drm device found!" << std::endl; sf::err() << "No drm device found!" << std::endl;
@ -685,7 +693,7 @@ void DRMContext::setVerticalSyncEnabled(bool enabled)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void DRMContext::createContext(DRMContext* shared) void DRMContext::createContext(DRMContext* shared)
{ {
const EGLint contextVersion[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; static constexpr std::array contextVersion = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE};
EGLContext toShared = nullptr; EGLContext toShared = nullptr;
@ -698,7 +706,7 @@ void DRMContext::createContext(DRMContext* shared)
eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
// Create EGL context // Create EGL context
m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion)); m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion.data()));
if (m_context == EGL_NO_CONTEXT) if (m_context == EGL_NO_CONTEXT)
err() << "Failed to create EGL context" << std::endl; err() << "Failed to create EGL context" << std::endl;
} }
@ -751,7 +759,7 @@ void DRMContext::destroySurface()
EGLConfig DRMContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixel, const ContextSettings& settings) EGLConfig DRMContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixel, const ContextSettings& settings)
{ {
// Set our video settings constraint // Set our video settings constraint
const EGLint attributes[] = const std::array attributes =
{ EGL_BUFFER_SIZE, { EGL_BUFFER_SIZE,
static_cast<EGLint>(bitsPerPixel), static_cast<EGLint>(bitsPerPixel),
EGL_DEPTH_SIZE, EGL_DEPTH_SIZE,
@ -781,10 +789,10 @@ EGLConfig DRMContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixe
EGL_NONE }; EGL_NONE };
EGLint configCount = 0; EGLint configCount = 0;
EGLConfig configs[1]; std::array<EGLConfig, 1> configs{};
// Ask EGL for the best config matching our video settings // Ask EGL for the best config matching our video settings
eglCheck(eglChooseConfig(display, attributes, configs, 1, &configCount)); eglCheck(eglChooseConfig(display, attributes.data(), configs.data(), configs.size(), &configCount));
return configs[0]; return configs[0];
} }

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <fcntl.h> #include <fcntl.h>
#include <linux/input.h> #include <linux/input.h>
#include <mutex> #include <mutex>
@ -107,15 +108,15 @@ void uninitFileDescriptors()
// Joysticks are handled in /src/SFML/Window/Unix/JoystickImpl.cpp // Joysticks are handled in /src/SFML/Window/Unix/JoystickImpl.cpp
bool keepFileDescriptor(int fileDesc) bool keepFileDescriptor(int fileDesc)
{ {
unsigned long bitmaskEv[NBITS(EV_MAX)]; std::array<unsigned long, NBITS(EV_MAX)> bitmaskEv{};
unsigned long bitmaskKey[NBITS(KEY_MAX)]; std::array<unsigned long, NBITS(KEY_MAX)> bitmaskKey{};
unsigned long bitmaskAbs[NBITS(ABS_MAX)]; std::array<unsigned long, NBITS(ABS_MAX)> bitmaskAbs{};
unsigned long bitmaskRel[NBITS(REL_MAX)]; std::array<unsigned long, NBITS(REL_MAX)> bitmaskRel{};
ioctl(fileDesc, EVIOCGBIT(0, sizeof(bitmaskEv)), &bitmaskEv); ioctl(fileDesc, EVIOCGBIT(0, sizeof(bitmaskEv)), bitmaskEv.data());
ioctl(fileDesc, EVIOCGBIT(EV_KEY, sizeof(bitmaskKey)), &bitmaskKey); ioctl(fileDesc, EVIOCGBIT(EV_KEY, sizeof(bitmaskKey)), bitmaskKey.data());
ioctl(fileDesc, EVIOCGBIT(EV_ABS, sizeof(bitmaskAbs)), &bitmaskAbs); ioctl(fileDesc, EVIOCGBIT(EV_ABS, sizeof(bitmaskAbs)), bitmaskAbs.data());
ioctl(fileDesc, EVIOCGBIT(EV_REL, sizeof(bitmaskRel)), &bitmaskRel); ioctl(fileDesc, EVIOCGBIT(EV_REL, sizeof(bitmaskRel)), bitmaskRel.data());
// This is the keyboard test used by SDL. // This is the keyboard test used by SDL.
// The first 32 bits are ESC, numbers and Q to D; If we have any of those, // The first 32 bits are ESC, numbers and Q to D; If we have any of those,
@ -514,8 +515,8 @@ std::optional<sf::Event> eventProcess()
ready = select(STDIN_FILENO + 1, &readFDSet, nullptr, nullptr, &timeout); ready = select(STDIN_FILENO + 1, &readFDSet, nullptr, nullptr, &timeout);
if (ready > 0 && FD_ISSET(STDIN_FILENO, &readFDSet)) if (ready > 0 && FD_ISSET(STDIN_FILENO, &readFDSet))
{ {
unsigned char tempBuffer[16]; std::array<unsigned char, 16> tempBuffer{};
bytesRead = read(STDIN_FILENO, tempBuffer, 16); bytesRead = read(STDIN_FILENO, tempBuffer.data(), tempBuffer.size());
code = 0; code = 0;
} }
} }

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <SFML/System/Sleep.hpp> #include <SFML/System/Sleep.hpp>
#include <array>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <ostream> #include <ostream>
@ -126,9 +127,9 @@ EglContext::EglContext(EglContext* shared)
// Note: The EGL specs say that attribList can be a null pointer when passed to eglCreatePbufferSurface, // Note: The EGL specs say that attribList can be a null pointer when passed to eglCreatePbufferSurface,
// but this is resulting in a segfault. Bug in Android? // but this is resulting in a segfault. Bug in Android?
EGLint attribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; static constexpr std::array attribList = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
m_surface = eglCheck(eglCreatePbufferSurface(m_display, m_config, attribList)); m_surface = eglCheck(eglCreatePbufferSurface(m_display, m_config, attribList.data()));
// Create EGL context // Create EGL context
createContext(shared); createContext(shared);
@ -251,7 +252,7 @@ void EglContext::setVerticalSyncEnabled(bool enabled)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void EglContext::createContext(EglContext* shared) void EglContext::createContext(EglContext* shared)
{ {
const EGLint contextVersion[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; static constexpr std::array contextVersion = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE};
EGLContext toShared = nullptr; EGLContext toShared = nullptr;
@ -264,7 +265,7 @@ void EglContext::createContext(EglContext* shared)
eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
// Create EGL context // Create EGL context
m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion)); m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion.data()));
} }
@ -296,6 +297,7 @@ EGLConfig EglContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixe
eglCheck(eglGetConfigs(display, nullptr, 0, &configCount)); eglCheck(eglGetConfigs(display, nullptr, 0, &configCount));
// Retrieve the list of available configs // Retrieve the list of available configs
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto configs = std::make_unique<EGLConfig[]>(static_cast<std::size_t>(configCount)); const auto configs = std::make_unique<EGLConfig[]>(static_cast<std::size_t>(configCount));
eglCheck(eglGetConfigs(display, configs.get(), configCount, &configCount)); eglCheck(eglGetConfigs(display, configs.get(), configCount, &configCount));
@ -414,6 +416,7 @@ XVisualInfo EglContext::selectBestVisual(::Display* xDisplay, unsigned int bitsP
// Get X11 visuals compatible with this EGL config // Get X11 visuals compatible with this EGL config
int visualCount = 0; int visualCount = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto availableVisuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(xDisplay, VisualIDMask, &vTemplate, &visualCount)); const auto availableVisuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(xDisplay, VisualIDMask, &vTemplate, &visualCount));
if (visualCount == 0) if (visualCount == 0)

View File

@ -300,6 +300,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
// Retrieve all the visuals // Retrieve all the visuals
int count = 0; int count = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
if (const auto visuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(display, 0, nullptr, &count))) if (const auto visuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(display, 0, nullptr, &count)))
{ {
// Evaluate all the returned visuals, and pick the best one // Evaluate all the returned visuals, and pick the best one
@ -478,6 +479,7 @@ void GlxContext::createSurface(GlxContext* shared, Vector2u size, unsigned int b
// the visual we are matching against was already // the visual we are matching against was already
// deemed suitable in selectBestVisual() // deemed suitable in selectBestVisual()
int nbConfigs = 0; int nbConfigs = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto configs = X11Ptr<GLXFBConfig[]>( const auto configs = X11Ptr<GLXFBConfig[]>(
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs)); glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs));
@ -497,7 +499,7 @@ void GlxContext::createSurface(GlxContext* shared, Vector2u size, unsigned int b
if (config) if (config)
{ {
std::array attributes = const std::array attributes =
{GLX_PBUFFER_WIDTH, static_cast<int>(size.x), GLX_PBUFFER_HEIGHT, static_cast<int>(size.y), 0, 0}; {GLX_PBUFFER_WIDTH, static_cast<int>(size.x), GLX_PBUFFER_HEIGHT, static_cast<int>(size.y), 0, 0};
m_pbuffer = glXCreatePbuffer(m_display.get(), *config, attributes.data()); m_pbuffer = glXCreatePbuffer(m_display.get(), *config, attributes.data());
@ -562,7 +564,7 @@ void GlxContext::createContext(GlxContext* shared)
glXQueryDrawable(m_display.get(), m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId); glXQueryDrawable(m_display.get(), m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId);
std::array attributes = {GLX_FBCONFIG_ID, static_cast<int>(fbConfigId), 0, 0}; const std::array attributes = {GLX_FBCONFIG_ID, static_cast<int>(fbConfigId), 0, 0};
int count = 0; int count = 0;
const auto fbconfig = X11Ptr<GLXFBConfig>( const auto fbconfig = X11Ptr<GLXFBConfig>(
@ -618,6 +620,7 @@ void GlxContext::createContext(GlxContext* shared)
// the visual we are matching against was already // the visual we are matching against was already
// deemed suitable in selectBestVisual() // deemed suitable in selectBestVisual()
int nbConfigs = 0; int nbConfigs = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto configs = X11Ptr<GLXFBConfig[]>( const auto configs = X11Ptr<GLXFBConfig[]>(
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs)); glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs));

View File

@ -468,7 +468,7 @@ void ensureMapping()
// Phase 2: Get XKB names with key code // Phase 2: Get XKB names with key code
const auto display = sf::priv::openDisplay(); const auto display = sf::priv::openDisplay();
char name[XkbKeyNameLength + 1]; std::array<char, XkbKeyNameLength + 1> name{};
XkbDescPtr descriptor = XkbGetMap(display.get(), 0, XkbUseCoreKbd); XkbDescPtr descriptor = XkbGetMap(display.get(), 0, XkbUseCoreKbd);
XkbGetNames(display.get(), XkbKeyNamesMask, descriptor); XkbGetNames(display.get(), XkbKeyNamesMask, descriptor);
@ -481,10 +481,10 @@ void ensureMapping()
continue; continue;
} }
std::memcpy(name, descriptor->names->keys[keycode].name, XkbKeyNameLength); std::memcpy(name.data(), descriptor->names->keys[keycode].name, XkbKeyNameLength);
name[XkbKeyNameLength] = '\0'; name[XkbKeyNameLength] = '\0';
const auto mappedScancode = nameScancodeMap.find(std::string(name)); const auto mappedScancode = nameScancodeMap.find(std::string(name.data()));
auto scancode = sf::Keyboard::Scan::Unknown; auto scancode = sf::Keyboard::Scan::Unknown;
if (mappedScancode != nameScancodeMap.end()) if (mappedScancode != nameScancodeMap.end())
@ -586,8 +586,8 @@ bool isKeyPressedImpl(KeyCode keycode)
const auto display = sf::priv::openDisplay(); const auto display = sf::priv::openDisplay();
// Get the whole keyboard state // Get the whole keyboard state
char keys[32]; std::array<char, 32> keys{};
XQueryKeymap(display.get(), keys); XQueryKeymap(display.get(), keys.data());
// Check our keycode // Check our keycode
return (keys[keycode / 8] & (1 << (keycode % 8))) != 0; return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;

View File

@ -77,6 +77,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{ {
// Get the list of supported depths // Get the list of supported depths
int nbDepths = 0; int nbDepths = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto depths = X11Ptr<int[]>(XListDepths(display.get(), screen, &nbDepths)); const auto depths = X11Ptr<int[]>(XListDepths(display.get(), screen, &nbDepths));
if (depths && (nbDepths > 0)) if (depths && (nbDepths > 0))
{ {

View File

@ -1837,12 +1837,12 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
if (m_inputContext) if (m_inputContext)
{ {
Status status = 0; Status status = 0;
std::uint8_t keyBuffer[64]; std::array<std::uint8_t, 64> keyBuffer{};
const int length = Xutf8LookupString(m_inputContext, const int length = Xutf8LookupString(m_inputContext,
&windowEvent.xkey, &windowEvent.xkey,
reinterpret_cast<char*>(keyBuffer), reinterpret_cast<char*>(keyBuffer.data()),
sizeof(keyBuffer), keyBuffer.size(),
nullptr, nullptr,
&status); &status);
@ -1856,10 +1856,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
// There might be more than 1 characters in this event, // There might be more than 1 characters in this event,
// so we must iterate it // so we must iterate it
std::uint32_t unicode = 0; std::uint32_t unicode = 0;
std::uint8_t* iter = keyBuffer; std::uint8_t* iter = keyBuffer.data();
while (iter < keyBuffer + length) while (iter < keyBuffer.data() + length)
{ {
iter = Utf8::decode(iter, keyBuffer + length, unicode, 0); iter = Utf8::decode(iter, keyBuffer.data() + length, unicode, 0);
if (unicode != 0) if (unicode != 0)
pushEvent(Event::TextEntered{unicode}); pushEvent(Event::TextEntered{unicode});
} }
@ -1868,8 +1868,8 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
else else
{ {
static XComposeStatus status; static XComposeStatus status;
char keyBuffer[16]; std::array<char, 16> keyBuffer{};
if (XLookupString(&windowEvent.xkey, keyBuffer, sizeof(keyBuffer), nullptr, &status)) if (XLookupString(&windowEvent.xkey, keyBuffer.data(), keyBuffer.size(), nullptr, &status))
pushEvent(Event::TextEntered{static_cast<std::uint32_t>(keyBuffer[0])}); pushEvent(Event::TextEntered{static_cast<std::uint32_t>(keyBuffer[0])});
} }
} }

View File

@ -635,8 +635,7 @@ String getDescription(Keyboard::Scancode code)
return *consumerKeyName; return *consumerKeyName;
WORD winCode = sfScanToWinScanExtended(code); WORD winCode = sfScanToWinScanExtended(code);
const int bufSize = 1024; std::array<WCHAR, 1024> name{};
WCHAR name[bufSize];
// Remap F13-F23 to values supported by GetKeyNameText // Remap F13-F23 to values supported by GetKeyNameText
if ((winCode >= 0x64) && (winCode <= 0x6E)) if ((winCode >= 0x64) && (winCode <= 0x6E))
@ -645,11 +644,9 @@ String getDescription(Keyboard::Scancode code)
if (winCode == 0x76) if (winCode == 0x76)
winCode = 0x87; winCode = 0x87;
const int result = GetKeyNameText(winCode << 16, name, bufSize); if (GetKeyNameText(winCode << 16, name.data(), static_cast<int>(name.size())) > 0)
if (result > 0) return name.data();
{
return name;
}
return "Unknown"; return "Unknown";
} }

View File

@ -34,6 +34,7 @@
#include <SFML/System/Win32/WindowsHeader.hpp> #include <SFML/System/Win32/WindowsHeader.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <iomanip> #include <iomanip>
#include <ostream> #include <ostream>
#include <regstr.h> #include <regstr.h>
@ -112,7 +113,7 @@ struct ConnectionCache
sf::Clock timer; sf::Clock timer;
}; };
ConnectionCache connectionCache[sf::Joystick::Count]; std::array<ConnectionCache, sf::Joystick::Count> connectionCache{};
// If true, will only update when WM_DEVICECHANGE message is received // If true, will only update when WM_DEVICECHANGE message is received
bool lazyUpdates = false; bool lazyUpdates = false;
@ -121,7 +122,7 @@ bool lazyUpdates = false;
sf::String getDeviceName(unsigned int index, JOYCAPS caps) sf::String getDeviceName(unsigned int index, JOYCAPS caps)
{ {
// Give the joystick a default name // Give the joystick a default name
sf::String joystickDescription = "Unknown Joystick"; static const sf::String joystickDescription = "Unknown Joystick";
LONG result = 0; LONG result = 0;
HKEY rootKey = nullptr; HKEY rootKey = nullptr;
@ -157,10 +158,10 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
subkey += indexString.str(); subkey += indexString.str();
subkey += REGSTR_VAL_JOYOEMNAME; subkey += REGSTR_VAL_JOYOEMNAME;
TCHAR keyData[256]; std::array<TCHAR, 256> keyData{};
DWORD keyDataSize = sizeof(keyData); DWORD keyDataSize = sizeof(keyData);
result = RegQueryValueEx(currentKey, subkey.c_str(), nullptr, nullptr, reinterpret_cast<LPBYTE>(keyData), &keyDataSize); result = RegQueryValueEx(currentKey, subkey.c_str(), nullptr, nullptr, reinterpret_cast<LPBYTE>(keyData.data()), &keyDataSize);
RegCloseKey(currentKey); RegCloseKey(currentKey);
if (result != ERROR_SUCCESS) if (result != ERROR_SUCCESS)
@ -172,7 +173,7 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
subkey = REGSTR_PATH_JOYOEM; subkey = REGSTR_PATH_JOYOEM;
subkey += TEXT('\\'); subkey += TEXT('\\');
subkey.append(keyData, keyDataSize / sizeof(TCHAR)); subkey.append(keyData.data(), keyDataSize / sizeof(TCHAR));
result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey); result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
@ -185,7 +186,7 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
keyDataSize = sizeof(keyData); keyDataSize = sizeof(keyData);
result = RegQueryValueEx(currentKey, REGSTR_VAL_JOYOEMNAME, nullptr, nullptr, reinterpret_cast<LPBYTE>(keyData), &keyDataSize); result = RegQueryValueEx(currentKey, REGSTR_VAL_JOYOEMNAME, nullptr, nullptr, reinterpret_cast<LPBYTE>(keyData.data()), &keyDataSize);
RegCloseKey(currentKey); RegCloseKey(currentKey);
if (result != ERROR_SUCCESS) if (result != ERROR_SUCCESS)
@ -195,10 +196,8 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
return joystickDescription; return joystickDescription;
} }
keyData[255] = TEXT('\0'); // Ensure null terminator in case the data is too long. keyData.back() = TEXT('\0'); // Ensure null terminator in case the data is too long.
joystickDescription = keyData; return keyData.data();
return joystickDescription;
} }
} // namespace } // namespace
@ -520,11 +519,8 @@ bool JoystickImpl::openDInput(unsigned int index)
// Initialize DirectInput members // Initialize DirectInput members
m_device = nullptr; m_device = nullptr;
for (int& axis : m_axes) m_axes.fill(-1);
axis = -1; m_buttons.fill(-1);
for (int& button : m_buttons)
button = -1;
m_deviceCaps = {}; m_deviceCaps = {};
m_deviceCaps.dwSize = sizeof(DIDEVCAPS); m_deviceCaps.dwSize = sizeof(DIDEVCAPS);
@ -594,9 +590,9 @@ bool JoystickImpl::openDInput(unsigned int index)
const DWORD povType = DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE; const DWORD povType = DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE;
const DWORD buttonType = DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE; const DWORD buttonType = DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE;
static DIOBJECTDATAFORMAT data[8 * 4 + 4 + sf::Joystick::ButtonCount]; static std::array<DIOBJECTDATAFORMAT, 8 * 4 + 4 + sf::Joystick::ButtonCount> data{};
for (int i = 0; i < 4; ++i) for (std::size_t i = 0; i < 4; ++i)
{ {
data[8 * i + 0].pguid = &guids::GUID_XAxis; data[8 * i + 0].pguid = &guids::GUID_XAxis;
data[8 * i + 1].pguid = &guids::GUID_YAxis; data[8 * i + 1].pguid = &guids::GUID_YAxis;
@ -641,13 +637,13 @@ bool JoystickImpl::openDInput(unsigned int index)
data[30].dwOfs = FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]); data[30].dwOfs = FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]);
data[31].dwOfs = FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]); data[31].dwOfs = FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]);
for (int i = 0; i < 8 * 4; ++i) for (std::size_t i = 0; i < 8 * 4; ++i)
{ {
data[i].dwType = axisType; data[i].dwType = axisType;
data[i].dwFlags = 0; data[i].dwFlags = 0;
} }
for (int i = 0; i < 4; ++i) for (std::size_t i = 0; i < 4; ++i)
{ {
data[8 * 4 + i].pguid = &guids::GUID_POV; data[8 * 4 + i].pguid = &guids::GUID_POV;
data[8 * 4 + i].dwOfs = static_cast<DWORD>(DIJOFS_POV(static_cast<unsigned int>(i))); data[8 * 4 + i].dwOfs = static_cast<DWORD>(DIJOFS_POV(static_cast<unsigned int>(i)));
@ -668,7 +664,7 @@ bool JoystickImpl::openDInput(unsigned int index)
format.dwFlags = DIDFT_ABSAXIS; format.dwFlags = DIDFT_ABSAXIS;
format.dwDataSize = sizeof(DIJOYSTATE2); format.dwDataSize = sizeof(DIJOYSTATE2);
format.dwNumObjs = 8 * 4 + 4 + sf::Joystick::ButtonCount; format.dwNumObjs = 8 * 4 + 4 + sf::Joystick::ButtonCount;
format.rgodf = data; format.rgodf = data.data();
formatInitialized = true; formatInitialized = true;
} }
@ -877,17 +873,17 @@ JoystickState JoystickImpl::updateDInputBuffered()
if (!m_device) if (!m_device)
return m_state; return m_state;
DIDEVICEOBJECTDATA events[directInputEventBufferSize]; std::array<DIDEVICEOBJECTDATA, directInputEventBufferSize> events{};
DWORD eventCount = directInputEventBufferSize; DWORD eventCount = directInputEventBufferSize;
// Try to get the device data // Try to get the device data
HRESULT result = m_device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), events, &eventCount, 0); HRESULT result = m_device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), events.data(), &eventCount, 0);
// If we have not acquired or have lost the device, attempt to (re-)acquire it and get the device data again // If we have not acquired or have lost the device, attempt to (re-)acquire it and get the device data again
if ((result == DIERR_NOTACQUIRED) || (result == DIERR_INPUTLOST)) if ((result == DIERR_NOTACQUIRED) || (result == DIERR_INPUTLOST))
{ {
m_device->Acquire(); m_device->Acquire();
result = m_device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), events, &eventCount, 0); result = m_device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), events.data(), &eventCount, 0);
} }
// If we still can't get the device data, assume it has been disconnected // If we still can't get the device data, assume it has been disconnected

View File

@ -218,7 +218,7 @@ private:
IDirectInputDevice8W* m_device{}; //!< DirectInput 8.x device IDirectInputDevice8W* m_device{}; //!< DirectInput 8.x device
DIDEVCAPS m_deviceCaps{}; //!< DirectInput device capabilities DIDEVCAPS m_deviceCaps{}; //!< DirectInput device capabilities
EnumArray<Joystick::Axis, int, Joystick::AxisCount> m_axes{}; //!< Offsets to the bytes containing the axes states, -1 if not available EnumArray<Joystick::Axis, int, Joystick::AxisCount> m_axes{}; //!< Offsets to the bytes containing the axes states, -1 if not available
int m_buttons[Joystick::ButtonCount]{}; //!< Offsets to the bytes containing the button states, -1 if not available std::array<int, Joystick::ButtonCount> m_buttons{}; //!< Offsets to the bytes containing the button states, -1 if not available
Joystick::Identification m_identification; //!< Joystick identification Joystick::Identification m_identification; //!< Joystick identification
JoystickState m_state; //!< Buffered joystick state JoystickState m_state; //!< Buffered joystick state
bool m_buffered{}; //!< `true` if the device uses buffering, `false` if the device uses polling bool m_buffered{}; //!< `true` if the device uses buffering, `false` if the device uses polling

View File

@ -295,7 +295,8 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
if (SF_GLAD_WGL_ARB_pixel_format) if (SF_GLAD_WGL_ARB_pixel_format)
{ {
// Define the basic attributes we want for our window // Define the basic attributes we want for our window
int intAttributes[] = {WGL_DRAW_TO_WINDOW_ARB, static constexpr std::array intAttributes =
{WGL_DRAW_TO_WINDOW_ARB,
GL_TRUE, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, WGL_SUPPORT_OPENGL_ARB,
GL_TRUE, GL_TRUE,
@ -307,9 +308,14 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
0}; 0};
// Check how many formats are supporting our requirements // Check how many formats are supporting our requirements
int formats[512]; std::array<int, 512> formats{};
UINT nbFormats = 0; // We must initialize to 0 otherwise broken drivers might fill with garbage in the following call UINT nbFormats = 0; // We must initialize to 0 otherwise broken drivers might fill with garbage in the following call
const bool isValid = wglChoosePixelFormatARB(deviceContext, intAttributes, nullptr, 512, formats, &nbFormats) != FALSE; const bool isValid = wglChoosePixelFormatARB(deviceContext,
intAttributes.data(),
nullptr,
static_cast<UINT>(formats.size()),
formats.data(),
&nbFormats) != FALSE;
if (!isValid) if (!isValid)
err() << "Failed to enumerate pixel formats: " << getErrorString(GetLastError()) << std::endl; err() << "Failed to enumerate pixel formats: " << getErrorString(GetLastError()) << std::endl;
@ -321,8 +327,9 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
for (UINT i = 0; i < nbFormats; ++i) for (UINT i = 0; i < nbFormats; ++i)
{ {
// Extract the components of the current format // Extract the components of the current format
int values[7]; std::array<int, 7> values{};
const int attributes[] = {WGL_RED_BITS_ARB, static constexpr std::array attributes =
{WGL_RED_BITS_ARB,
WGL_GREEN_BITS_ARB, WGL_GREEN_BITS_ARB,
WGL_BLUE_BITS_ARB, WGL_BLUE_BITS_ARB,
WGL_ALPHA_BITS_ARB, WGL_ALPHA_BITS_ARB,
@ -330,19 +337,28 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
WGL_STENCIL_BITS_ARB, WGL_STENCIL_BITS_ARB,
WGL_ACCELERATION_ARB}; WGL_ACCELERATION_ARB};
if (wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 7, attributes, values) == FALSE) if (wglGetPixelFormatAttribivARB(deviceContext,
formats[i],
PFD_MAIN_PLANE,
static_cast<UINT>(values.size()),
attributes.data(),
values.data()) == FALSE)
{ {
err() << "Failed to retrieve pixel format information: " << getErrorString(GetLastError()) << std::endl; err() << "Failed to retrieve pixel format information: " << getErrorString(GetLastError()) << std::endl;
break; break;
} }
int sampleValues[2] = {0, 0}; std::array sampleValues = {0, 0};
if (SF_GLAD_WGL_ARB_multisample) if (SF_GLAD_WGL_ARB_multisample)
{ {
const int sampleAttributes[] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB}; static constexpr std::array sampleAttributes = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
if (wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues) == if (wglGetPixelFormatAttribivARB(deviceContext,
FALSE) formats[i],
PFD_MAIN_PLANE,
static_cast<UINT>(sampleAttributes.size()),
sampleAttributes.data(),
sampleValues.data()) == FALSE)
{ {
err() << "Failed to retrieve pixel format multisampling information: " err() << "Failed to retrieve pixel format multisampling information: "
<< getErrorString(GetLastError()) << std::endl; << getErrorString(GetLastError()) << std::endl;
@ -366,12 +382,16 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
if (pbuffer) if (pbuffer)
{ {
const int pbufferAttributes[] = {WGL_DRAW_TO_PBUFFER_ARB}; static constexpr std::array pbufferAttributes = {WGL_DRAW_TO_PBUFFER_ARB};
int pbufferValue = 0; int pbufferValue = 0;
if (wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, pbufferAttributes, &pbufferValue) == if (wglGetPixelFormatAttribivARB(deviceContext,
FALSE) formats[i],
PFD_MAIN_PLANE,
static_cast<UINT>(pbufferAttributes.size()),
pbufferAttributes.data(),
&pbufferValue) == FALSE)
{ {
err() << "Failed to retrieve pixel format pbuffer information: " << getErrorString(GetLastError()) err() << "Failed to retrieve pixel format pbuffer information: " << getErrorString(GetLastError())
<< std::endl; << std::endl;
@ -501,10 +521,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_pixel_format) if (SF_GLAD_WGL_ARB_pixel_format)
{ {
const int attributes[] = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB}; static constexpr std::array attributes = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB};
int values[2]; std::array<int, 2> values{};
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, attributes, values) == TRUE) if (wglGetPixelFormatAttribivARB(m_deviceContext,
format,
PFD_MAIN_PLANE,
static_cast<UINT>(attributes.size()),
attributes.data(),
values.data()) == TRUE)
{ {
m_settings.depthBits = static_cast<unsigned int>(values[0]); m_settings.depthBits = static_cast<unsigned int>(values[0]);
m_settings.stencilBits = static_cast<unsigned int>(values[1]); m_settings.stencilBits = static_cast<unsigned int>(values[1]);
@ -518,11 +543,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_multisample) if (SF_GLAD_WGL_ARB_multisample)
{ {
const int sampleAttributes[] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB}; static constexpr std::array sampleAttributes = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
int sampleValues[2]; std::array<int, 2> sampleValues{};
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues) == if (wglGetPixelFormatAttribivARB(m_deviceContext,
TRUE) format,
PFD_MAIN_PLANE,
static_cast<UINT>(sampleAttributes.size()),
sampleAttributes.data(),
sampleValues.data()) == TRUE)
{ {
m_settings.antiAliasingLevel = static_cast<unsigned int>(sampleValues[0] ? sampleValues[1] : 0); m_settings.antiAliasingLevel = static_cast<unsigned int>(sampleValues[0] ? sampleValues[1] : 0);
} }
@ -540,11 +569,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_framebuffer_sRGB || SF_GLAD_WGL_EXT_framebuffer_sRGB) if (SF_GLAD_WGL_ARB_framebuffer_sRGB || SF_GLAD_WGL_EXT_framebuffer_sRGB)
{ {
const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; static constexpr std::array sRgbCapableAttribute = {WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB};
int sRgbCapableValue = 0; int sRgbCapableValue = 0;
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue) == if (wglGetPixelFormatAttribivARB(m_deviceContext,
TRUE) format,
PFD_MAIN_PLANE,
static_cast<UINT>(sRgbCapableAttribute.size()),
sRgbCapableAttribute.data(),
&sRgbCapableValue) == TRUE)
{ {
m_settings.sRgbCapable = (sRgbCapableValue == TRUE); m_settings.sRgbCapable = (sRgbCapableValue == TRUE);
} }
@ -579,13 +612,13 @@ void WglContext::createSurface(WglContext* shared, Vector2u size, unsigned int b
if (bestFormat > 0) if (bestFormat > 0)
{ {
int attributes[] = {0, 0}; static constexpr std::array attributes = {0, 0};
m_pbuffer = wglCreatePbufferARB(shared->m_deviceContext, m_pbuffer = wglCreatePbufferARB(shared->m_deviceContext,
bestFormat, bestFormat,
static_cast<int>(size.x), static_cast<int>(size.x),
static_cast<int>(size.y), static_cast<int>(size.y),
attributes); attributes.data());
if (m_pbuffer) if (m_pbuffer)
{ {

View File

@ -36,6 +36,7 @@
// dbt.h is lowercase here, as a cross-compile on linux with mingw-w64 // dbt.h is lowercase here, as a cross-compile on linux with mingw-w64
// expects lowercase, and a native compile on windows, whether via msvc // expects lowercase, and a native compile on windows, whether via msvc
// or mingw-w64 addresses files in a case insensitive manner. // or mingw-w64 addresses files in a case insensitive manner.
#include <array>
#include <dbt.h> #include <dbt.h>
#include <ostream> #include <ostream>
#include <vector> #include <vector>
@ -863,8 +864,8 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
if ((character >= 0xDC00) && (character <= 0xDFFF)) if ((character >= 0xDC00) && (character <= 0xDFFF))
{ {
// Convert the UTF-16 surrogate pair to a single UTF-32 value // Convert the UTF-16 surrogate pair to a single UTF-32 value
std::uint16_t utf16[] = {m_surrogate, static_cast<std::uint16_t>(character)}; const std::array utf16 = {m_surrogate, static_cast<std::uint16_t>(character)};
sf::Utf16::toUtf32(utf16, utf16 + 2, &character); sf::Utf16::toUtf32(utf16.begin(), utf16.end(), &character);
m_surrogate = 0; m_surrogate = 0;
} }

View File

@ -36,6 +36,7 @@
#include <OpenGLES/EAGL.h> #include <OpenGLES/EAGL.h>
#include <OpenGLES/EAGLDrawable.h> #include <OpenGLES/EAGLDrawable.h>
#include <QuartzCore/CAEAGLLayer.h> #include <QuartzCore/CAEAGLLayer.h>
#include <array>
#include <dlfcn.h> #include <dlfcn.h>
#include <ostream> #include <ostream>
@ -162,12 +163,11 @@ GlFunctionPointer EaglContext::getFunction(const char* name)
{ {
static void* module = nullptr; static void* module = nullptr;
const int libCount = 3; static constexpr std::array libs = {"libGLESv1_CM.dylib",
const char* libs[libCount] = {"libGLESv1_CM.dylib",
"/System/Library/Frameworks/OpenGLES.framework/OpenGLES", "/System/Library/Frameworks/OpenGLES.framework/OpenGLES",
"OpenGLES.framework/OpenGLES"}; "OpenGLES.framework/OpenGLES"};
for (auto& lib : libs) for (const auto& lib : libs)
{ {
if (!module) if (!module)
module = dlopen(lib, RTLD_LAZY | RTLD_LOCAL); module = dlopen(lib, RTLD_LAZY | RTLD_LOCAL);

View File

@ -31,6 +31,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <AppKit/AppKit.h> #include <AppKit/AppKit.h>
#include <array>
#include <ostream> #include <ostream>
namespace namespace
@ -868,8 +869,7 @@ void HIDInputManager::buildMappings()
if (translateToString) if (translateToString)
{ {
// Unicode string length is usually less or equal to 4 // Unicode string length is usually less or equal to 4
const UniCharCount maxLength = 4; std::array<UniChar, 4> string{};
UniChar string[maxLength];
UniCharCount length = 0; UniCharCount length = 0;
std::uint32_t deadKeyState = 0; // unused value std::uint32_t deadKeyState = 0; // unused value
const std::uint32_t modifiers = 0x100; // no modifiers const std::uint32_t modifiers = 0x100; // no modifiers
@ -882,9 +882,9 @@ void HIDInputManager::buildMappings()
LMGetKbdType(), LMGetKbdType(),
kUCKeyTranslateNoDeadKeysMask, kUCKeyTranslateNoDeadKeysMask,
&deadKeyState, &deadKeyState,
maxLength, string.size(),
&length, &length,
string); string.data());
if (error != noErr) if (error != noErr)
{ {

View File

@ -28,6 +28,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#import <SFML/Window/macOS/NSImage+raw.h> #import <SFML/Window/macOS/NSImage+raw.h>
#include <array>
@implementation NSImage (raw) @implementation NSImage (raw)
+ (NSImage*)imageWithRawData:(const std::uint8_t*)pixels andSize:(NSSize)size + (NSImage*)imageWithRawData:(const std::uint8_t*)pixels andSize:(NSSize)size
@ -50,8 +52,8 @@
{ {
for (unsigned int x = 0; x < size.width; ++x, pixels += 4) for (unsigned int x = 0; x < size.width; ++x, pixels += 4)
{ {
NSUInteger pixel[4] = {pixels[0], pixels[1], pixels[2], pixels[3]}; std::array<NSUInteger, 4> pixel = {pixels[0], pixels[1], pixels[2], pixels[3]};
[bitmap setPixel:pixel atX:x y:y]; [bitmap setPixel:pixel.data() atX:x y:y];
} }
} }

View File

@ -10,6 +10,7 @@
#include <GraphicsUtil.hpp> #include <GraphicsUtil.hpp>
#include <WindowUtil.hpp> #include <WindowUtil.hpp>
#include <array>
#include <type_traits> #include <type_traits>
TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
@ -273,10 +274,10 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
SECTION("Copy semantics") SECTION("Copy semantics")
{ {
constexpr std::uint8_t red[] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; static constexpr std::array<std::uint8_t, 8> red = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF};
sf::Texture texture(sf::Vector2u(1, 2)); sf::Texture texture(sf::Vector2u(1, 2));
texture.update(red); texture.update(red.data());
SECTION("Construction") SECTION("Construction")
{ {
@ -296,21 +297,21 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
SECTION("update()") SECTION("update()")
{ {
constexpr std::uint8_t yellow[] = {0xFF, 0xFF, 0x00, 0xFF}; static constexpr std::array<std::uint8_t, 4> yellow = {0xFF, 0xFF, 0x00, 0xFF};
constexpr std::uint8_t cyan[] = {0x00, 0xFF, 0xFF, 0xFF}; static constexpr std::array<std::uint8_t, 4> cyan = {0x00, 0xFF, 0xFF, 0xFF};
SECTION("Pixels") SECTION("Pixels")
{ {
sf::Texture texture(sf::Vector2u(1, 1)); sf::Texture texture(sf::Vector2u(1, 1));
texture.update(yellow); texture.update(yellow.data());
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow);
} }
SECTION("Pixels, size and destination") SECTION("Pixels, size and destination")
{ {
sf::Texture texture(sf::Vector2u(2, 1)); sf::Texture texture(sf::Vector2u(2, 1));
texture.update(yellow, sf::Vector2u(1, 1), sf::Vector2u(0, 0)); texture.update(yellow.data(), sf::Vector2u(1, 1), sf::Vector2u(0, 0));
texture.update(cyan, sf::Vector2u(1, 1), sf::Vector2u(1, 0)); texture.update(cyan.data(), sf::Vector2u(1, 1), sf::Vector2u(1, 0));
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow);
CHECK(texture.copyToImage().getPixel(sf::Vector2u(1, 0)) == sf::Color::Cyan); CHECK(texture.copyToImage().getPixel(sf::Vector2u(1, 0)) == sf::Color::Cyan);
} }
@ -318,7 +319,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
SECTION("Another texture") SECTION("Another texture")
{ {
sf::Texture otherTexture(sf::Vector2u(1, 1)); sf::Texture otherTexture(sf::Vector2u(1, 1));
otherTexture.update(cyan); otherTexture.update(cyan.data());
sf::Texture texture(sf::Vector2u(1, 1)); sf::Texture texture(sf::Vector2u(1, 1));
texture.update(otherTexture); texture.update(otherTexture);
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan);
@ -328,9 +329,9 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
{ {
sf::Texture texture(sf::Vector2u(2, 1)); sf::Texture texture(sf::Vector2u(2, 1));
sf::Texture otherTexture1(sf::Vector2u(1, 1)); sf::Texture otherTexture1(sf::Vector2u(1, 1));
otherTexture1.update(cyan); otherTexture1.update(cyan.data());
sf::Texture otherTexture2(sf::Vector2u(1, 1)); sf::Texture otherTexture2(sf::Vector2u(1, 1));
otherTexture2.update(yellow); otherTexture2.update(yellow.data());
texture.update(otherTexture1, sf::Vector2u(0, 0)); texture.update(otherTexture1, sf::Vector2u(0, 0));
texture.update(otherTexture2, sf::Vector2u(1, 0)); texture.update(otherTexture2, sf::Vector2u(1, 0));
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan);
@ -386,16 +387,16 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
SECTION("swap()") SECTION("swap()")
{ {
constexpr std::uint8_t blue[] = {0x00, 0x00, 0xFF, 0xFF}; static constexpr std::array<std::uint8_t, 4> blue = {0x00, 0x00, 0xFF, 0xFF};
constexpr std::uint8_t green[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; static constexpr std::array<std::uint8_t, 8> green = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF};
sf::Texture texture1(sf::Vector2u(1, 1), true); sf::Texture texture1(sf::Vector2u(1, 1), true);
texture1.update(blue); texture1.update(blue.data());
texture1.setSmooth(false); texture1.setSmooth(false);
texture1.setRepeated(true); texture1.setRepeated(true);
sf::Texture texture2(sf::Vector2u(2, 1), false); sf::Texture texture2(sf::Vector2u(2, 1), false);
texture2.update(green); texture2.update(green.data());
texture2.setSmooth(true); texture2.setSmooth(true);
texture2.setRepeated(false); texture2.setRepeated(false);

View File

@ -239,7 +239,7 @@ TEST_CASE("[Network] sf::Packet")
SECTION("char*") SECTION("char*")
{ {
const char string[] = "testing"; const char string[] = "testing"; // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
CHECK_PACKET_STRING_STREAM_OPERATORS(string, std::strlen(string) + 4); CHECK_PACKET_STRING_STREAM_OPERATORS(string, std::strlen(string) + 4);
} }
@ -251,7 +251,7 @@ TEST_CASE("[Network] sf::Packet")
SECTION("wchar_t*") SECTION("wchar_t*")
{ {
const wchar_t string[] = L"testing"; const wchar_t string[] = L"testing"; // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
CHECK_PACKET_STRING_STREAM_OPERATORS(string, 4 * std::wcslen(string) + 4); CHECK_PACKET_STRING_STREAM_OPERATORS(string, 4 * std::wcslen(string) + 4);
} }

View File

@ -2,6 +2,7 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <array>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -73,7 +74,7 @@ TEST_CASE("[System] sf::FileInputStream")
} }
const TemporaryFile temporaryFile("Hello world"); const TemporaryFile temporaryFile("Hello world");
char buffer[32]; std::array<char, 32> buffer{};
SECTION("Construction") SECTION("Construction")
{ {
@ -89,10 +90,10 @@ TEST_CASE("[System] sf::FileInputStream")
SECTION("File path constructor") SECTION("File path constructor")
{ {
sf::FileInputStream fileInputStream(temporaryFile.getPath()); sf::FileInputStream fileInputStream(temporaryFile.getPath());
CHECK(fileInputStream.read(buffer, 5) == 5); CHECK(fileInputStream.read(buffer.data(), 5) == 5);
CHECK(fileInputStream.tell() == 5); CHECK(fileInputStream.tell() == 5);
CHECK(fileInputStream.getSize() == 11); CHECK(fileInputStream.getSize() == 11);
CHECK(std::string_view(buffer, 5) == "Hello"sv); CHECK(std::string_view(buffer.data(), 5) == "Hello"sv);
CHECK(fileInputStream.seek(6) == 6); CHECK(fileInputStream.seek(6) == 6);
CHECK(fileInputStream.tell() == 6); CHECK(fileInputStream.tell() == 6);
} }
@ -104,10 +105,10 @@ TEST_CASE("[System] sf::FileInputStream")
{ {
sf::FileInputStream movedFileInputStream(temporaryFile.getPath()); sf::FileInputStream movedFileInputStream(temporaryFile.getPath());
sf::FileInputStream fileInputStream = std::move(movedFileInputStream); sf::FileInputStream fileInputStream = std::move(movedFileInputStream);
CHECK(fileInputStream.read(buffer, 6) == 6); CHECK(fileInputStream.read(buffer.data(), 6) == 6);
CHECK(fileInputStream.tell() == 6); CHECK(fileInputStream.tell() == 6);
CHECK(fileInputStream.getSize() == 11); CHECK(fileInputStream.getSize() == 11);
CHECK(std::string_view(buffer, 6) == "Hello "sv); CHECK(std::string_view(buffer.data(), 6) == "Hello "sv);
} }
SECTION("Move assignment") SECTION("Move assignment")
@ -116,10 +117,10 @@ TEST_CASE("[System] sf::FileInputStream")
const TemporaryFile temporaryFile2("Hello world the sequel"); const TemporaryFile temporaryFile2("Hello world the sequel");
sf::FileInputStream fileInputStream(temporaryFile2.getPath()); sf::FileInputStream fileInputStream(temporaryFile2.getPath());
fileInputStream = std::move(movedFileInputStream); fileInputStream = std::move(movedFileInputStream);
CHECK(fileInputStream.read(buffer, 6) == 6); CHECK(fileInputStream.read(buffer.data(), 6) == 6);
CHECK(fileInputStream.tell() == 6); CHECK(fileInputStream.tell() == 6);
CHECK(fileInputStream.getSize() == 11); CHECK(fileInputStream.getSize() == 11);
CHECK(std::string_view(buffer, 6) == "Hello "sv); CHECK(std::string_view(buffer.data(), 6) == "Hello "sv);
} }
} }
@ -127,10 +128,10 @@ TEST_CASE("[System] sf::FileInputStream")
{ {
sf::FileInputStream fileInputStream; sf::FileInputStream fileInputStream;
REQUIRE(fileInputStream.open(temporaryFile.getPath())); REQUIRE(fileInputStream.open(temporaryFile.getPath()));
CHECK(fileInputStream.read(buffer, 5) == 5); CHECK(fileInputStream.read(buffer.data(), 5) == 5);
CHECK(fileInputStream.tell() == 5); CHECK(fileInputStream.tell() == 5);
CHECK(fileInputStream.getSize() == 11); CHECK(fileInputStream.getSize() == 11);
CHECK(std::string_view(buffer, 5) == "Hello"sv); CHECK(std::string_view(buffer.data(), 5) == "Hello"sv);
CHECK(fileInputStream.seek(6) == 6); CHECK(fileInputStream.seek(6) == 6);
CHECK(fileInputStream.tell() == 6); CHECK(fileInputStream.tell() == 6);
} }
@ -138,10 +139,10 @@ TEST_CASE("[System] sf::FileInputStream")
SECTION("Temporary file stream create") SECTION("Temporary file stream create")
{ {
sf::FileInputStream fileInputStream(temporaryFile.getPath()); sf::FileInputStream fileInputStream(temporaryFile.getPath());
CHECK(fileInputStream.read(buffer, 5) == 5); CHECK(fileInputStream.read(buffer.data(), 5) == 5);
CHECK(fileInputStream.tell() == 5); CHECK(fileInputStream.tell() == 5);
CHECK(fileInputStream.getSize() == 11); CHECK(fileInputStream.getSize() == 11);
CHECK(std::string_view(buffer, 5) == "Hello"sv); CHECK(std::string_view(buffer.data(), 5) == "Hello"sv);
CHECK(fileInputStream.seek(6) == 6); CHECK(fileInputStream.seek(6) == 6);
CHECK(fileInputStream.tell() == 6); CHECK(fileInputStream.tell() == 6);
} }

View File

@ -78,8 +78,8 @@ TEST_CASE("[System] sf::U8StringCharTraits")
SECTION("assign(char_type*, std::size_t, char_type)") SECTION("assign(char_type*, std::size_t, char_type)")
{ {
sf::U8StringCharTraits::char_type s[] = {'a', 'b', 'c', '\0'}; std::array<sf::U8StringCharTraits::char_type, 4> s = {'a', 'b', 'c', '\0'};
CHECK(sf::U8StringCharTraits::assign(s, 2, 'd') == &s[0]); CHECK(sf::U8StringCharTraits::assign(s.data(), 2, 'd') == s.data());
CHECK(s[0] == 'd'); CHECK(s[0] == 'd');
CHECK(s[1] == 'd'); CHECK(s[1] == 'd');
CHECK(s[2] == 'c'); CHECK(s[2] == 'c');
@ -103,9 +103,9 @@ TEST_CASE("[System] sf::U8StringCharTraits")
SECTION("move()") SECTION("move()")
{ {
sf::U8StringCharTraits::char_type s1[] = {'a', 'b', 'c', '\0'}; std::array<sf::U8StringCharTraits::char_type, 4> s1 = {'a', 'b', 'c', '\0'};
const sf::U8StringCharTraits::char_type s2[] = {'d', 'e', 'f', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 4> s2 = {'d', 'e', 'f', '\0'};
CHECK(sf::U8StringCharTraits::move(s1, s2, std::size(s2)) == s1); CHECK(sf::U8StringCharTraits::move(s1.data(), s2.data(), s2.size()) == s1.data());
CHECK(s1[0] == 'd'); CHECK(s1[0] == 'd');
CHECK(s1[1] == 'e'); CHECK(s1[1] == 'e');
CHECK(s1[2] == 'f'); CHECK(s1[2] == 'f');
@ -116,9 +116,9 @@ TEST_CASE("[System] sf::U8StringCharTraits")
SECTION("copy()") SECTION("copy()")
{ {
sf::U8StringCharTraits::char_type s1[] = {'a', 'b', 'c', '\0'}; std::array<sf::U8StringCharTraits::char_type, 4> s1 = {'a', 'b', 'c', '\0'};
const sf::U8StringCharTraits::char_type s2[] = {'d', 'e', 'f', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 4> s2 = {'d', 'e', 'f', '\0'};
CHECK(sf::U8StringCharTraits::copy(s1, s2, std::size(s2)) == s1); CHECK(sf::U8StringCharTraits::copy(s1.data(), s2.data(), s2.size()) == s1.data());
CHECK(s1[0] == 'd'); CHECK(s1[0] == 'd');
CHECK(s1[1] == 'e'); CHECK(s1[1] == 'e');
CHECK(s1[2] == 'f'); CHECK(s1[2] == 'f');
@ -129,27 +129,27 @@ TEST_CASE("[System] sf::U8StringCharTraits")
SECTION("compare()") SECTION("compare()")
{ {
const sf::U8StringCharTraits::char_type s1[] = {'a', 'b', 'c', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 4> s1 = {'a', 'b', 'c', '\0'};
const sf::U8StringCharTraits::char_type s2[] = {'a', 'b', 'c', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 4> s2 = {'a', 'b', 'c', '\0'};
const sf::U8StringCharTraits::char_type s3[] = {'d', 'e', 'f', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 4> s3 = {'d', 'e', 'f', '\0'};
CHECK(sf::U8StringCharTraits::compare(s1, s2, std::size(s1)) == 0); CHECK(sf::U8StringCharTraits::compare(s1.data(), s2.data(), s1.size()) == 0);
CHECK(sf::U8StringCharTraits::compare(s1, s3, std::size(s1)) < 0); CHECK(sf::U8StringCharTraits::compare(s1.data(), s3.data(), s1.size()) < 0);
CHECK(sf::U8StringCharTraits::compare(s3, s1, std::size(s3)) > 0); CHECK(sf::U8StringCharTraits::compare(s3.data(), s1.data(), s3.size()) > 0);
} }
SECTION("length()") SECTION("length()")
{ {
const sf::U8StringCharTraits::char_type s1[] = {'a', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 2> s1 = {'a', '\0'};
const sf::U8StringCharTraits::char_type s2[] = {'a', 'b', 'c', 'd', 'e', '\0'}; const std::array<sf::U8StringCharTraits::char_type, 6> s2 = {'a', 'b', 'c', 'd', 'e', '\0'};
CHECK(sf::U8StringCharTraits::length(s1) == 1); CHECK(sf::U8StringCharTraits::length(s1.data()) == 1);
CHECK(sf::U8StringCharTraits::length(s2) == 5); CHECK(sf::U8StringCharTraits::length(s2.data()) == 5);
} }
SECTION("find()") SECTION("find()")
{ {
const sf::U8StringCharTraits::char_type s[] = {'a', 'b', 'c', 'd', 'e'}; const std::array<sf::U8StringCharTraits::char_type, 5> s = {'a', 'b', 'c', 'd', 'e'};
CHECK(*sf::U8StringCharTraits::find(s, std::size(s), 'a') == 'a'); CHECK(*sf::U8StringCharTraits::find(s.data(), s.size(), 'a') == 'a');
CHECK(sf::U8StringCharTraits::find(s, std::size(s), 'f') == nullptr); CHECK(sf::U8StringCharTraits::find(s.data(), s.size(), 'f') == nullptr);
} }
SECTION("to_char_type()") SECTION("to_char_type()")