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

View File

@ -8,6 +8,7 @@
#include <iomanip>
#include <iostream>
#include <optional>
#include <string_view>
#include <cstddef>
@ -34,17 +35,17 @@ void runTcpServer(unsigned short port)
std::cout << "Client connected: " << socket.getRemoteAddress().value() << std::endl;
// Send a message to the connected client
const char out[] = "Hi, I'm the server";
if (socket.send(out, sizeof(out)) != sf::Socket::Status::Done)
static constexpr std::string_view out = "Hi, I'm the server";
if (socket.send(out.data(), out.size()) != sf::Socket::Status::Done)
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
char in[128];
std::size_t received = 0;
if (socket.receive(in, sizeof(in), received) != sf::Socket::Status::Done)
std::array<char, 128> in{};
std::size_t received = 0;
if (socket.receive(in.data(), in.size(), received) != sf::Socket::Status::Done)
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;
// Receive a message from the server
char in[128];
std::size_t received = 0;
if (socket.receive(in, sizeof(in), received) != sf::Socket::Status::Done)
std::array<char, 128> in{};
std::size_t received = 0;
if (socket.receive(in.data(), in.size(), received) != sf::Socket::Status::Done)
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
const char out[] = "Hi, I'm a client";
if (socket.send(out, sizeof(out)) != sf::Socket::Status::Done)
static constexpr std::string_view out = "Hi, I'm a client";
if (socket.send(out.data(), out.size()) != sf::Socket::Status::Done)
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 <iostream>
#include <optional>
#include <string_view>
#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;
// Wait for a message
char in[128];
std::array<char, 128> in{};
std::size_t received = 0;
std::optional<sf::IpAddress> sender;
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;
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
const char out[] = "Hi, I'm the server";
if (socket.send(out, sizeof(out), sender.value(), senderPort) != sf::Socket::Status::Done)
static constexpr std::string_view out = "Hi, I'm the server";
if (socket.send(out.data(), out.size(), sender.value(), senderPort) != sf::Socket::Status::Done)
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;
// Send a message to the server
const char out[] = "Hi, I'm a client";
if (socket.send(out, sizeof(out), server.value(), port) != sf::Socket::Status::Done)
static constexpr std::string_view out = "Hi, I'm a client";
if (socket.send(out.data(), out.size(), server.value(), port) != sf::Socket::Status::Done)
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)
char in[128];
std::array<char, 128> in{};
std::size_t received = 0;
std::optional<sf::IpAddress> sender;
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;
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 <algorithm>
#include <array>
#include <iostream>
#include <limits>
#include <memory>
@ -1018,7 +1019,7 @@ private:
{
public:
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,
-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,
@ -1052,12 +1053,12 @@ private:
}
private:
AllPassFilter<T> m_allPass[4];
FIRFilter<T> m_fir;
std::vector<T> m_buffer;
std::size_t m_cursor{};
const std::size_t m_interval{m_buffer.size() / 3};
const float m_feedbackGain{};
std::array<AllPassFilter<T>, 4> m_allPass;
FIRFilter<T> m_fir;
std::vector<T> m_buffer;
std::size_t m_cursor{};
const std::size_t m_interval{m_buffer.size() / 3};
const float m_feedbackGain{};
};
};

View File

@ -26,21 +26,21 @@
////////////////////////////////////////////////////////////
namespace
{
using Matrix = float[4][4];
using Matrix = std::array<std::array<float, 4>, 4>;
// Multiply 2 matrices
void matrixMultiply(Matrix& result, const Matrix& left, const Matrix& right)
{
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] +
left[3][j] * right[i][3];
}
std::memcpy(result, temp, sizeof(Matrix));
result = temp;
}
// Rotate a matrix around the x-axis
@ -49,12 +49,12 @@ void matrixRotateX(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians();
// clang-format off
const Matrix matrix = {
const Matrix matrix = {{
{1.f, 0.f, 0.f, 0.f},
{0.f, std::cos(rad), std::sin(rad), 0.f},
{0.f, -std::sin(rad), std::cos(rad), 0.f},
{0.f, 0.f, 0.f, 1.f}
};
}};
// clang-format on
matrixMultiply(result, result, matrix);
@ -66,12 +66,12 @@ void matrixRotateY(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians();
// clang-format off
const Matrix matrix = {
const Matrix matrix = {{
{ std::cos(rad), 0.f, std::sin(rad), 0.f},
{ 0.f, 1.f, 0.f, 0.f},
{-std::sin(rad), 0.f, std::cos(rad), 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
}};
// clang-format on
matrixMultiply(result, result, matrix);
@ -83,12 +83,12 @@ void matrixRotateZ(Matrix& result, sf::Angle angle)
const float rad = angle.asRadians();
// clang-format off
const Matrix matrix = {
const Matrix matrix = {{
{ std::cos(rad), std::sin(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, 0.f, 1.f}
};
}};
// clang-format on
matrixMultiply(result, result, matrix);
@ -705,7 +705,7 @@ public:
deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
// 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
VkPhysicalDeviceFeatures physicalDeviceFeatures = VkPhysicalDeviceFeatures();
@ -713,8 +713,8 @@ public:
VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo();
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.enabledExtensionCount = 1;
deviceCreateInfo.ppEnabledExtensionNames = extensions;
deviceCreateInfo.enabledExtensionCount = static_cast<std::uint32_t>(extensions.size());
deviceCreateInfo.ppEnabledExtensionNames = extensions.data();
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
@ -978,7 +978,7 @@ public:
// Setup renderpass and its subpass dependencies
void setupRenderpass()
{
VkAttachmentDescription attachmentDescriptions[2];
std::array<VkAttachmentDescription, 2> attachmentDescriptions{};
// Color attachment
attachmentDescriptions[0] = VkAttachmentDescription();
@ -1027,8 +1027,8 @@ public:
VkRenderPassCreateInfo renderPassCreateInfo = VkRenderPassCreateInfo();
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.attachmentCount = 2;
renderPassCreateInfo.pAttachments = attachmentDescriptions;
renderPassCreateInfo.attachmentCount = static_cast<std::uint32_t>(attachmentDescriptions.size());
renderPassCreateInfo.pAttachments = attachmentDescriptions.data();
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpassDescription;
renderPassCreateInfo.dependencyCount = 1;
@ -1045,7 +1045,7 @@ public:
// Set up uniform buffer and texture sampler descriptor set layouts
void setupDescriptorSetLayout()
{
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[2];
std::array<VkDescriptorSetLayoutBinding, 2> descriptorSetLayoutBindings{};
// Layout binding for uniform buffer
descriptorSetLayoutBindings[0] = VkDescriptorSetLayoutBinding();
@ -1063,8 +1063,8 @@ public:
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = VkDescriptorSetLayoutCreateInfo();
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.bindingCount = 2;
descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
descriptorSetLayoutCreateInfo.bindingCount = static_cast<std::uint32_t>(descriptorSetLayoutBindings.size());
descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings.data();
// Create descriptor set layout
if (vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
@ -1100,7 +1100,7 @@ public:
vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
// 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
vertexInputAttributeDescriptions[0] = VkVertexInputAttributeDescription();
@ -1127,8 +1127,9 @@ public:
vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 3;
vertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(
vertexInputAttributeDescriptions.size());
vertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions.data();
// We want to generate a triangle list with our vertex data
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo();
@ -1204,8 +1205,8 @@ public:
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = VkGraphicsPipelineCreateInfo();
graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
graphicsPipelineCreateInfo.stageCount = 2;
graphicsPipelineCreateInfo.pStages = shaderStages;
graphicsPipelineCreateInfo.stageCount = static_cast<std::uint32_t>(shaderStages.size());
graphicsPipelineCreateInfo.pStages = shaderStages.data();
graphicsPipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo;
graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo;
graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo;
@ -1242,9 +1243,9 @@ public:
for (std::size_t i = 0; i < swapchainFramebuffers.size(); ++i)
{
// 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
if (vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &swapchainFramebuffers[i]) != VK_SUCCESS)
@ -2130,7 +2131,7 @@ public:
void setupDescriptorPool()
{
// 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].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@ -2142,8 +2143,8 @@ public:
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = VkDescriptorPoolCreateInfo();
descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCreateInfo.poolSizeCount = 2;
descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
descriptorPoolCreateInfo.poolSizeCount = static_cast<std::uint32_t>(descriptorPoolSizes.size());
descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes.data();
descriptorPoolCreateInfo.maxSets = static_cast<std::uint32_t>(swapchainImages.size());
// 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 (std::size_t i = 0; i < descriptorSets.size(); ++i)
{
VkWriteDescriptorSet writeDescriptorSets[2];
std::array<VkWriteDescriptorSet, 2> writeDescriptorSets{};
// Uniform buffer binding information
VkDescriptorBufferInfo descriptorBufferInfo = VkDescriptorBufferInfo();
@ -2212,7 +2213,11 @@ public:
writeDescriptorSets[1].pImageInfo = &descriptorImageInfo;
// 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()
{
// Set up our clear colors
VkClearValue clearColors[2];
std::array<VkClearValue, 2> clearColors{};
// Clear color buffer to opaque black
clearColors[0] = VkClearValue();
@ -2262,8 +2267,8 @@ public:
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent = swapchainExtent;
renderPassBeginInfo.clearValueCount = 2;
renderPassBeginInfo.pClearValues = clearColors;
renderPassBeginInfo.clearValueCount = static_cast<std::uint32_t>(clearColors.size());
renderPassBeginInfo.pClearValues = clearColors.data();
// Simultaneous use: this command buffer can be resubmitted to a queue before a previous submission is completed
VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
@ -2380,7 +2385,14 @@ public:
void updateUniformBuffer(float elapsed)
{
// 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));
matrixRotateY(model, sf::degrees(elapsed * 83.0f));
@ -2424,9 +2436,9 @@ public:
}
// 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) * 1, view, sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 2, projection, sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 0, model.data(), sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 1, view.data(), sizeof(Matrix));
std::memcpy(ptr + sizeof(Matrix) * 2, projection.data(), sizeof(Matrix));
// Unmap the buffer
vkUnmapMemory(device, uniformBuffersMemory[currentFrame]);
@ -2561,47 +2573,47 @@ private:
unsigned int currentFrame{};
bool swapchainOutOfDate{};
VkInstance instance{};
VkDebugReportCallbackEXT debugReportCallback{};
VkSurfaceKHR surface{};
VkPhysicalDevice gpu{};
std::optional<std::uint32_t> queueFamilyIndex;
VkDevice device{};
VkQueue queue{};
VkSurfaceFormatKHR swapchainFormat{};
VkExtent2D swapchainExtent{};
VkSwapchainKHR swapchain{};
std::vector<VkImage> swapchainImages;
std::vector<VkImageView> swapchainImageViews;
VkFormat depthFormat{VK_FORMAT_UNDEFINED};
VkImage depthImage{};
VkDeviceMemory depthImageMemory{};
VkImageView depthImageView{};
VkShaderModule vertexShaderModule{};
VkShaderModule fragmentShaderModule{};
VkPipelineShaderStageCreateInfo shaderStages[2]{};
VkDescriptorSetLayout descriptorSetLayout{};
VkPipelineLayout pipelineLayout{};
VkRenderPass renderPass{};
VkPipeline graphicsPipeline{};
std::vector<VkFramebuffer> swapchainFramebuffers;
VkCommandPool commandPool{};
VkBuffer vertexBuffer{};
VkDeviceMemory vertexBufferMemory{};
VkBuffer indexBuffer{};
VkDeviceMemory indexBufferMemory{};
std::vector<VkBuffer> uniformBuffers;
std::vector<VkDeviceMemory> uniformBuffersMemory;
VkImage textureImage{};
VkDeviceMemory textureImageMemory{};
VkImageView textureImageView{};
VkSampler textureSampler{};
VkDescriptorPool descriptorPool{};
std::vector<VkDescriptorSet> descriptorSets;
std::vector<VkCommandBuffer> commandBuffers;
std::vector<VkSemaphore> imageAvailableSemaphores;
std::vector<VkSemaphore> renderFinishedSemaphores;
std::vector<VkFence> fences;
VkInstance instance{};
VkDebugReportCallbackEXT debugReportCallback{};
VkSurfaceKHR surface{};
VkPhysicalDevice gpu{};
std::optional<std::uint32_t> queueFamilyIndex;
VkDevice device{};
VkQueue queue{};
VkSurfaceFormatKHR swapchainFormat{};
VkExtent2D swapchainExtent{};
VkSwapchainKHR swapchain{};
std::vector<VkImage> swapchainImages;
std::vector<VkImageView> swapchainImageViews;
VkFormat depthFormat{VK_FORMAT_UNDEFINED};
VkImage depthImage{};
VkDeviceMemory depthImageMemory{};
VkImageView depthImageView{};
VkShaderModule vertexShaderModule{};
VkShaderModule fragmentShaderModule{};
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages{};
VkDescriptorSetLayout descriptorSetLayout{};
VkPipelineLayout pipelineLayout{};
VkRenderPass renderPass{};
VkPipeline graphicsPipeline{};
std::vector<VkFramebuffer> swapchainFramebuffers;
VkCommandPool commandPool{};
VkBuffer vertexBuffer{};
VkDeviceMemory vertexBufferMemory{};
VkBuffer indexBuffer{};
VkDeviceMemory indexBufferMemory{};
std::vector<VkBuffer> uniformBuffers;
std::vector<VkDeviceMemory> uniformBuffersMemory;
VkImage textureImage{};
VkDeviceMemory textureImageMemory{};
VkImageView textureImageView{};
VkSampler textureSampler{};
VkDescriptorPool descriptorPool{};
std::vector<VkDescriptorSet> descriptorSets;
std::vector<VkCommandBuffer> commandBuffers;
std::vector<VkSemaphore> imageAvailableSemaphores;
std::vector<VkSemaphore> renderFinishedSemaphores;
std::vector<VkFence> fences;
// NOLINTEND(readability-identifier-naming)
};

View File

@ -319,11 +319,11 @@ private:
/// << "sample count: " << file.getSampleCount() << std::endl;
///
/// // 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;
/// do
/// {
/// count = file.read(samples, 1024);
/// count = file.read(samples.data(), samples.size());
///
/// // process, analyze, play, convert, or whatever
/// // you want to do with the samples...

View File

@ -30,6 +30,8 @@
#include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/Glsl.hpp> // NOLINT(misc-header-include-cycle)
#include <array>
#include <cstddef>
@ -74,7 +76,7 @@ struct Matrix
////////////////////////////////////////////////////////////
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);
}
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:
/// \code
/// sf::Vertex vertices[15];
/// std::array<sf::Vertex, 15> vertices;
/// ...
/// sf::VertexBuffer triangles(sf::PrimitiveType::Triangles);
/// triangles.create(15);
/// triangles.update(vertices);
/// triangles.create(vertices.size());
/// triangles.update(vertices.data());
/// ...
/// window.draw(triangles);
/// \endcode

View File

@ -285,10 +285,10 @@ private:
/// socket.send(message.c_str(), message.size() + 1);
///
/// // Receive an answer from the server
/// char buffer[1024];
/// std::array<char, 1024> buffer;
/// std::size_t received = 0;
/// socket.receive(buffer, sizeof(buffer), received);
/// std::cout << "The server said: " << buffer << std::endl;
/// socket.receive(buffer.data(), buffer.size(), received);
/// std::cout << "The server said: " << buffer.data() << std::endl;
///
/// // ----- The server -----
///
@ -302,10 +302,10 @@ private:
/// std::cout << "New client connected: " << socket.getRemoteAddress().value() << std::endl;
///
/// // Receive a message from the client
/// char buffer[1024];
/// std::array<char, 1024> buffer;
/// std::size_t received = 0;
/// socket.receive(buffer, sizeof(buffer), received);
/// std::cout << "The client said: " << buffer << std::endl;
/// socket.receive(buffer.data(), buffer.size(), received);
/// std::cout << "The client said: " << buffer.data() << std::endl;
///
/// // Send an answer
/// 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);
///
/// // 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::optional<sf::IpAddress> sender;
/// unsigned short port;
/// if (socket.receive(buffer, sizeof(buffer), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer << std::endl;
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
///
/// // ----- The server -----
///
@ -276,12 +276,12 @@ private:
/// socket.bind(55002);
///
/// // Receive a message from anyone
/// char buffer[1024];
/// std::array<char, 1024> buffer;
/// std::size_t received = 0;
/// std::optional<sf::IpAddress> sender;
/// unsigned short port;
/// if (socket.receive(buffer, sizeof(buffer), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer << std::endl;
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
///
/// // Send an answer
/// std::string message = "Welcome " + sender.toString();

View File

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

View File

@ -56,6 +56,7 @@
#include <SFML/System/InputStream.hpp>
#include <algorithm>
#include <array>
#include <ostream>
#include <cassert>
@ -90,15 +91,15 @@ namespace sf::priv
////////////////////////////////////////////////////////////
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;
if (hasValidId3Tag(header))
if (hasValidId3Tag(header.data()))
return true;
if (hdr_valid(header))
if (hdr_valid(header.data()))
return true;
return false;

View File

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

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");
// 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());
// Write the main chunk header
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());
// 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());
if (channelCount > 2)
@ -295,13 +295,13 @@ void SoundFileWriterWav::writeHeader(unsigned int sampleRate, unsigned int chann
encode(m_file, bitsPerSample);
encode(m_file, channelMask);
// 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'};
m_file.write(subformat.data(), subformat.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());
const std::uint32_t dataChunkSize = 0; // placeholder, will be written later
encode(m_file, dataChunkSize);

View File

@ -40,7 +40,7 @@ namespace sf::priv
void copyMatrix(const Transform& source, Matrix<3, 3>& dest)
{
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)
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)
{
// 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/System/EnumArray.hpp>
#include <SFML/System/Err.hpp>
#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)
{
// Find the OpenGL primitive type
static constexpr GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN};
const GLenum mode = modes[static_cast<std::size_t>(type)];
static constexpr priv::EnumArray<PrimitiveType, GLenum, 6> modes =
{GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN};
const GLenum mode = modes[type];
// Draw the primitives
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);
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);
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)
{
const std::size_t matrixSize = 3 * 3;
static const std::size_t matrixSize = matrixArray[0].array.size();
std::vector<float> contiguous(matrixSize * length);
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);
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)
{
const std::size_t matrixSize = 4 * 4;
static const std::size_t matrixSize = matrixArray[0].array.size();
std::vector<float> contiguous(matrixSize * length);
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);
if (binder.location != -1)
@ -884,7 +884,7 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
if (success == GL_FALSE)
{
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;
glCheck(GLEXT_glDeleteObject(shader));
glCheck(GLEXT_glDeleteObject(shaderProgram));
@ -921,7 +921,7 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
if (success == GL_FALSE)
{
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;
glCheck(GLEXT_glDeleteObject(shaderProgram));
return false;

View File

@ -31,6 +31,7 @@
#include <SFML/System/Err.hpp>
#include <algorithm>
#include <array>
#include <fstream>
#include <ostream>
#include <sstream>
@ -381,23 +382,23 @@ Ftp::Response Ftp::getResponse()
for (;;)
{
// Receive the response from the server
char buffer[1024];
std::size_t length = 0;
std::array<char, 1024> buffer{};
std::size_t length = 0;
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);
}
else
{
std::copy(m_receiveBuffer.begin(), m_receiveBuffer.end(), buffer);
std::copy(m_receiveBuffer.begin(), m_receiveBuffer.end(), buffer.data());
length = m_receiveBuffer.size();
m_receiveBuffer.clear();
}
// 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)
{
// Try to extract the code
@ -451,7 +452,7 @@ Ftp::Response Ftp::getResponse()
}
// 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()));
// Return the response code and message
@ -526,9 +527,9 @@ Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode)
const std::string::size_type begin = response.getMessage().find_first_of("0123456789");
if (begin != std::string::npos)
{
std::uint8_t data[6] = {0, 0, 0, 0, 0, 0};
std::string str = response.getMessage().substr(begin);
std::size_t index = 0;
std::array<std::uint8_t, 6> data{};
std::string str = response.getMessage().substr(begin);
std::size_t index = 0;
for (unsigned char& datum : data)
{
// Extract the current number
@ -584,11 +585,11 @@ Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode)
void Ftp::DataChannel::receive(std::ostream& stream)
{
// Receive data
char buffer[1024];
std::size_t received = 0;
while (m_dataSocket.receive(buffer, sizeof(buffer), received) == Socket::Status::Done)
std::array<char, 1024> buffer{};
std::size_t received = 0;
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())
{
@ -606,13 +607,13 @@ void Ftp::DataChannel::receive(std::ostream& stream)
void Ftp::DataChannel::send(std::istream& stream)
{
// Send data
char buffer[1024];
std::size_t count = 0;
std::array<char, 1024> buffer{};
std::size_t count = 0;
for (;;)
{
// read some data from the stream
stream.read(buffer, sizeof(buffer));
stream.read(buffer.data(), buffer.size());
if (!stream.good() && !stream.eof())
{
@ -625,7 +626,7 @@ void Ftp::DataChannel::send(std::istream& stream)
if (count > 0)
{
// 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;
}
else

View File

@ -31,6 +31,7 @@
#include <SFML/System/Utils.hpp>
#include <algorithm>
#include <array>
#include <iterator>
#include <limits>
#include <ostream>
@ -375,12 +376,12 @@ Http::Response Http::sendRequest(const Http::Request& request, Time timeout)
if (m_connection.send(requestStr.c_str(), requestStr.size()) == Socket::Status::Done)
{
// Wait for the server's response
std::string receivedStr;
std::size_t size = 0;
char buffer[1024];
while (m_connection.receive(buffer, sizeof(buffer), size) == Socket::Status::Done)
std::string receivedStr;
std::size_t size = 0;
std::array<char, 1024> buffer{};
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

View File

@ -196,8 +196,8 @@ Packet& Packet::operator>>(std::int64_t& data)
{
// Since ntohll is not available everywhere, we have to convert
// to network byte order (big endian) manually
std::byte bytes[sizeof(data)];
std::memcpy(bytes, &m_data[m_readPos], sizeof(data));
std::array<std::byte, sizeof(data)> bytes{};
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]);
@ -434,16 +434,16 @@ Packet& Packet::operator<<(std::int64_t data)
// Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually
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 >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF),
static_cast<std::uint8_t>((data >> 24) & 0xFF),
static_cast<std::uint8_t>((data >> 16) & 0xFF),
static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 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 >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF),
static_cast<std::uint8_t>((data >> 24) & 0xFF),
static_cast<std::uint8_t>((data >> 16) & 0xFF),
static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 0xFF)};
append(&toWrite, sizeof(toWrite));
append(toWrite.data(), toWrite.size());
return *this;
}
@ -454,16 +454,16 @@ Packet& Packet::operator<<(std::uint64_t data)
// Since htonll is not available everywhere, we have to convert
// to network byte order (big endian) manually
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 >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF),
static_cast<std::uint8_t>((data >> 24) & 0xFF),
static_cast<std::uint8_t>((data >> 16) & 0xFF),
static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 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 >> 40) & 0xFF),
static_cast<std::uint8_t>((data >> 32) & 0xFF),
static_cast<std::uint8_t>((data >> 24) & 0xFF),
static_cast<std::uint8_t>((data >> 16) & 0xFF),
static_cast<std::uint8_t>((data >> 8) & 0xFF),
static_cast<std::uint8_t>((data) & 0xFF)};
append(&toWrite, sizeof(toWrite));
append(toWrite.data(), toWrite.size());
return *this;
}

View File

@ -402,7 +402,7 @@ Socket::Status TcpSocket::receive(Packet& packet)
while (m_pendingPacket.data.size() < packetSize)
{
// 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);
if (status != Status::Done)
return status;

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp>
#include <SFML/System/Sleep.hpp>
#include <array>
#include <fcntl.h>
#include <poll.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 format = gbm_bo_get_format(&bo);
std::uint32_t strides[4] = {0};
std::uint32_t handles[4] = {0};
std::uint32_t offsets[4] = {0};
std::uint64_t modifiers[4] = {0};
modifiers[0] = gbm_bo_get_modifier(&bo);
const int numPlanes = gbm_bo_get_plane_count(&bo);
std::array<std::uint32_t, 4> strides{};
std::array<std::uint32_t, 4> handles{};
std::array<std::uint32_t, 4> offsets{};
std::array<std::uint64_t, 4> modifiers{};
modifiers[0] = gbm_bo_get_modifier(&bo);
const int numPlanes = gbm_bo_get_plane_count(&bo);
for (int i = 0; i < numPlanes; ++i)
{
strides[i] = gbm_bo_get_stride_for_plane(&bo, i);
handles[i] = gbm_bo_get_handle(&bo).u32;
offsets[i] = gbm_bo_get_offset(&bo, i);
modifiers[i] = modifiers[0];
strides[static_cast<std::size_t>(i)] = gbm_bo_get_stride_for_plane(&bo, i);
handles[static_cast<std::size_t>(i)] = gbm_bo_get_handle(&bo).u32;
offsets[static_cast<std::size_t>(i)] = gbm_bo_get_offset(&bo, i);
modifiers[static_cast<std::size_t>(i)] = modifiers[0];
}
std::uint32_t flags = 0;
@ -179,16 +180,25 @@ DrmFb* drmFbGetFromBo(gbm_bo& bo)
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)
{
std::memset(handles, 0, 16);
handles.fill(0);
handles[0] = gbm_bo_get_handle(&bo).u32;
std::memset(strides, 0, 16);
strides.fill(0);
strides[0] = gbm_bo_get_stride(&bo);
std::memset(offsets, 0, 16);
result = drmModeAddFB2(drmFd, width, height, format, handles, strides, offsets, &fb->fbId, 0);
offsets.fill(0);
result = drmModeAddFB2(drmFd, width, height, format, handles.data(), strides.data(), offsets.data(), &fb->fbId, 0);
}
if (result)
@ -271,11 +281,9 @@ int hasMonitorConnected(int fd, drmModeRes& resources)
int findDrmDevice(drmModeResPtr& resources)
{
static const int maxDrmDevices = 64;
std::array<drmDevicePtr, 64> devices{};
drmDevicePtr devices[maxDrmDevices] = {};
const int numDevices = drmGetDevices2(0, devices, maxDrmDevices);
const int numDevices = drmGetDevices2(0, devices.data(), devices.size());
if (numDevices < 0)
{
sf::err() << "drmGetDevices2 failed: " << std::strerror(-numDevices) << std::endl;
@ -283,7 +291,7 @@ int findDrmDevice(drmModeResPtr& resources)
}
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];
int result = 0;
@ -303,7 +311,7 @@ int findDrmDevice(drmModeResPtr& resources)
close(fileDescriptor);
fileDescriptor = -1;
}
drmFreeDevices(devices, numDevices);
drmFreeDevices(devices.data(), numDevices);
if (fileDescriptor < 0)
sf::err() << "No drm device found!" << std::endl;
@ -685,7 +693,7 @@ void DRMContext::setVerticalSyncEnabled(bool enabled)
////////////////////////////////////////////////////////////
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;
@ -698,7 +706,7 @@ void DRMContext::createContext(DRMContext* shared)
eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_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)
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)
{
// Set our video settings constraint
const EGLint attributes[] =
const std::array attributes =
{ EGL_BUFFER_SIZE,
static_cast<EGLint>(bitsPerPixel),
EGL_DEPTH_SIZE,
@ -780,11 +788,11 @@ EGLConfig DRMContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixe
#endif
EGL_NONE };
EGLint configCount = 0;
EGLConfig configs[1];
EGLint configCount = 0;
std::array<EGLConfig, 1> configs{};
// 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];
}

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp>
#include <algorithm>
#include <array>
#include <fcntl.h>
#include <linux/input.h>
#include <mutex>
@ -107,15 +108,15 @@ void uninitFileDescriptors()
// Joysticks are handled in /src/SFML/Window/Unix/JoystickImpl.cpp
bool keepFileDescriptor(int fileDesc)
{
unsigned long bitmaskEv[NBITS(EV_MAX)];
unsigned long bitmaskKey[NBITS(KEY_MAX)];
unsigned long bitmaskAbs[NBITS(ABS_MAX)];
unsigned long bitmaskRel[NBITS(REL_MAX)];
std::array<unsigned long, NBITS(EV_MAX)> bitmaskEv{};
std::array<unsigned long, NBITS(KEY_MAX)> bitmaskKey{};
std::array<unsigned long, NBITS(ABS_MAX)> bitmaskAbs{};
std::array<unsigned long, NBITS(REL_MAX)> bitmaskRel{};
ioctl(fileDesc, EVIOCGBIT(0, sizeof(bitmaskEv)), &bitmaskEv);
ioctl(fileDesc, EVIOCGBIT(EV_KEY, sizeof(bitmaskKey)), &bitmaskKey);
ioctl(fileDesc, EVIOCGBIT(EV_ABS, sizeof(bitmaskAbs)), &bitmaskAbs);
ioctl(fileDesc, EVIOCGBIT(EV_REL, sizeof(bitmaskRel)), &bitmaskRel);
ioctl(fileDesc, EVIOCGBIT(0, sizeof(bitmaskEv)), bitmaskEv.data());
ioctl(fileDesc, EVIOCGBIT(EV_KEY, sizeof(bitmaskKey)), bitmaskKey.data());
ioctl(fileDesc, EVIOCGBIT(EV_ABS, sizeof(bitmaskAbs)), bitmaskAbs.data());
ioctl(fileDesc, EVIOCGBIT(EV_REL, sizeof(bitmaskRel)), bitmaskRel.data());
// 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,
@ -514,8 +515,8 @@ std::optional<sf::Event> eventProcess()
ready = select(STDIN_FILENO + 1, &readFDSet, nullptr, nullptr, &timeout);
if (ready > 0 && FD_ISSET(STDIN_FILENO, &readFDSet))
{
unsigned char tempBuffer[16];
bytesRead = read(STDIN_FILENO, tempBuffer, 16);
std::array<unsigned char, 16> tempBuffer{};
bytesRead = read(STDIN_FILENO, tempBuffer.data(), tempBuffer.size());
code = 0;
}
}

View File

@ -32,6 +32,7 @@
#include <SFML/System/Err.hpp>
#include <SFML/System/Sleep.hpp>
#include <array>
#include <memory>
#include <mutex>
#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,
// 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
createContext(shared);
@ -251,7 +252,7 @@ void EglContext::setVerticalSyncEnabled(bool enabled)
////////////////////////////////////////////////////////////
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;
@ -264,7 +265,7 @@ void EglContext::createContext(EglContext* shared)
eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_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));
// 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));
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
int visualCount = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto availableVisuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(xDisplay, VisualIDMask, &vTemplate, &visualCount));
if (visualCount == 0)

View File

@ -300,6 +300,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
// Retrieve all the visuals
int count = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
if (const auto visuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(display, 0, nullptr, &count)))
{
// Evaluate all the returned visuals, and pick the best one
@ -477,8 +478,9 @@ void GlxContext::createSurface(GlxContext* shared, Vector2u size, unsigned int b
// We don't supply attributes to match against, since
// the visual we are matching against was already
// deemed suitable in selectBestVisual()
int nbConfigs = 0;
const auto configs = X11Ptr<GLXFBConfig[]>(
int nbConfigs = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto configs = X11Ptr<GLXFBConfig[]>(
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs));
for (std::size_t i = 0; configs && (i < static_cast<std::size_t>(nbConfigs)); ++i)
@ -497,7 +499,7 @@ void GlxContext::createSurface(GlxContext* shared, Vector2u size, unsigned int b
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};
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);
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;
const auto fbconfig = X11Ptr<GLXFBConfig>(
@ -617,8 +619,9 @@ void GlxContext::createContext(GlxContext* shared)
// We don't supply attributes to match against, since
// the visual we are matching against was already
// deemed suitable in selectBestVisual()
int nbConfigs = 0;
const auto configs = X11Ptr<GLXFBConfig[]>(
int nbConfigs = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto configs = X11Ptr<GLXFBConfig[]>(
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs));
for (std::size_t i = 0; configs && (i < static_cast<std::size_t>(nbConfigs)); ++i)

View File

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

View File

@ -76,8 +76,9 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
if (sizes && (nbSizes > 0))
{
// Get the list of supported depths
int nbDepths = 0;
const auto depths = X11Ptr<int[]>(XListDepths(display.get(), screen, &nbDepths));
int nbDepths = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
const auto depths = X11Ptr<int[]>(XListDepths(display.get(), screen, &nbDepths));
if (depths && (nbDepths > 0))
{
// Combine depths and sizes to fill the array of supported modes

View File

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

View File

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

View File

@ -34,6 +34,7 @@
#include <SFML/System/Win32/WindowsHeader.hpp>
#include <algorithm>
#include <array>
#include <iomanip>
#include <ostream>
#include <regstr.h>
@ -112,7 +113,7 @@ struct ConnectionCache
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
bool lazyUpdates = false;
@ -121,7 +122,7 @@ bool lazyUpdates = false;
sf::String getDeviceName(unsigned int index, JOYCAPS caps)
{
// Give the joystick a default name
sf::String joystickDescription = "Unknown Joystick";
static const sf::String joystickDescription = "Unknown Joystick";
LONG result = 0;
HKEY rootKey = nullptr;
@ -157,10 +158,10 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
subkey += indexString.str();
subkey += REGSTR_VAL_JOYOEMNAME;
TCHAR keyData[256];
DWORD keyDataSize = sizeof(keyData);
std::array<TCHAR, 256> 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);
if (result != ERROR_SUCCESS)
@ -172,7 +173,7 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
subkey = REGSTR_PATH_JOYOEM;
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);
@ -185,7 +186,7 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
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);
if (result != ERROR_SUCCESS)
@ -195,10 +196,8 @@ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
return joystickDescription;
}
keyData[255] = TEXT('\0'); // Ensure null terminator in case the data is too long.
joystickDescription = keyData;
return joystickDescription;
keyData.back() = TEXT('\0'); // Ensure null terminator in case the data is too long.
return keyData.data();
}
} // namespace
@ -520,11 +519,8 @@ bool JoystickImpl::openDInput(unsigned int index)
// Initialize DirectInput members
m_device = nullptr;
for (int& axis : m_axes)
axis = -1;
for (int& button : m_buttons)
button = -1;
m_axes.fill(-1);
m_buttons.fill(-1);
m_deviceCaps = {};
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 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 + 1].pguid = &guids::GUID_YAxis;
@ -641,13 +637,13 @@ bool JoystickImpl::openDInput(unsigned int index)
data[30].dwOfs = FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]);
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].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].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.dwDataSize = sizeof(DIJOYSTATE2);
format.dwNumObjs = 8 * 4 + 4 + sf::Joystick::ButtonCount;
format.rgodf = data;
format.rgodf = data.data();
formatInitialized = true;
}
@ -877,17 +873,17 @@ JoystickState JoystickImpl::updateDInputBuffered()
if (!m_device)
return m_state;
DIDEVICEOBJECTDATA events[directInputEventBufferSize];
DWORD eventCount = directInputEventBufferSize;
std::array<DIDEVICEOBJECTDATA, directInputEventBufferSize> events{};
DWORD eventCount = directInputEventBufferSize;
// 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 ((result == DIERR_NOTACQUIRED) || (result == DIERR_INPUTLOST))
{
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

View File

@ -218,7 +218,7 @@ private:
IDirectInputDevice8W* m_device{}; //!< DirectInput 8.x device
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
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
JoystickState m_state; //!< Buffered joystick state
bool m_buffered{}; //!< `true` if the device uses buffering, `false` if the device uses polling

View File

@ -295,21 +295,27 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
if (SF_GLAD_WGL_ARB_pixel_format)
{
// Define the basic attributes we want for our window
int intAttributes[] = {WGL_DRAW_TO_WINDOW_ARB,
GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,
GL_TRUE,
WGL_DOUBLE_BUFFER_ARB,
GL_TRUE,
WGL_PIXEL_TYPE_ARB,
WGL_TYPE_RGBA_ARB,
0,
0};
static constexpr std::array intAttributes =
{WGL_DRAW_TO_WINDOW_ARB,
GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,
GL_TRUE,
WGL_DOUBLE_BUFFER_ARB,
GL_TRUE,
WGL_PIXEL_TYPE_ARB,
WGL_TYPE_RGBA_ARB,
0,
0};
// 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
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)
err() << "Failed to enumerate pixel formats: " << getErrorString(GetLastError()) << std::endl;
@ -321,28 +327,38 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
for (UINT i = 0; i < nbFormats; ++i)
{
// Extract the components of the current format
int values[7];
const int attributes[] = {WGL_RED_BITS_ARB,
WGL_GREEN_BITS_ARB,
WGL_BLUE_BITS_ARB,
WGL_ALPHA_BITS_ARB,
WGL_DEPTH_BITS_ARB,
WGL_STENCIL_BITS_ARB,
WGL_ACCELERATION_ARB};
std::array<int, 7> values{};
static constexpr std::array attributes =
{WGL_RED_BITS_ARB,
WGL_GREEN_BITS_ARB,
WGL_BLUE_BITS_ARB,
WGL_ALPHA_BITS_ARB,
WGL_DEPTH_BITS_ARB,
WGL_STENCIL_BITS_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;
break;
}
int sampleValues[2] = {0, 0};
std::array sampleValues = {0, 0};
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) ==
FALSE)
if (wglGetPixelFormatAttribivARB(deviceContext,
formats[i],
PFD_MAIN_PLANE,
static_cast<UINT>(sampleAttributes.size()),
sampleAttributes.data(),
sampleValues.data()) == FALSE)
{
err() << "Failed to retrieve pixel format multisampling information: "
<< getErrorString(GetLastError()) << std::endl;
@ -366,12 +382,16 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
if (pbuffer)
{
const int pbufferAttributes[] = {WGL_DRAW_TO_PBUFFER_ARB};
static constexpr std::array pbufferAttributes = {WGL_DRAW_TO_PBUFFER_ARB};
int pbufferValue = 0;
if (wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, pbufferAttributes, &pbufferValue) ==
FALSE)
if (wglGetPixelFormatAttribivARB(deviceContext,
formats[i],
PFD_MAIN_PLANE,
static_cast<UINT>(pbufferAttributes.size()),
pbufferAttributes.data(),
&pbufferValue) == FALSE)
{
err() << "Failed to retrieve pixel format pbuffer information: " << getErrorString(GetLastError())
<< std::endl;
@ -501,10 +521,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_pixel_format)
{
const int attributes[] = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB};
int values[2];
static constexpr std::array attributes = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB};
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.stencilBits = static_cast<unsigned int>(values[1]);
@ -518,11 +543,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_multisample)
{
const int sampleAttributes[] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
int sampleValues[2];
static constexpr std::array sampleAttributes = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
std::array<int, 2> sampleValues{};
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues) ==
TRUE)
if (wglGetPixelFormatAttribivARB(m_deviceContext,
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);
}
@ -540,11 +569,15 @@ void WglContext::updateSettingsFromPixelFormat()
if (SF_GLAD_WGL_ARB_framebuffer_sRGB || SF_GLAD_WGL_EXT_framebuffer_sRGB)
{
const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
int sRgbCapableValue = 0;
static constexpr std::array sRgbCapableAttribute = {WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB};
int sRgbCapableValue = 0;
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue) ==
TRUE)
if (wglGetPixelFormatAttribivARB(m_deviceContext,
format,
PFD_MAIN_PLANE,
static_cast<UINT>(sRgbCapableAttribute.size()),
sRgbCapableAttribute.data(),
&sRgbCapableValue) == TRUE)
{
m_settings.sRgbCapable = (sRgbCapableValue == TRUE);
}
@ -579,13 +612,13 @@ void WglContext::createSurface(WglContext* shared, Vector2u size, unsigned int b
if (bestFormat > 0)
{
int attributes[] = {0, 0};
static constexpr std::array attributes = {0, 0};
m_pbuffer = wglCreatePbufferARB(shared->m_deviceContext,
bestFormat,
static_cast<int>(size.x),
static_cast<int>(size.y),
attributes);
attributes.data());
if (m_pbuffer)
{

View File

@ -36,6 +36,7 @@
// 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
// or mingw-w64 addresses files in a case insensitive manner.
#include <array>
#include <dbt.h>
#include <ostream>
#include <vector>
@ -863,8 +864,8 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
if ((character >= 0xDC00) && (character <= 0xDFFF))
{
// Convert the UTF-16 surrogate pair to a single UTF-32 value
std::uint16_t utf16[] = {m_surrogate, static_cast<std::uint16_t>(character)};
sf::Utf16::toUtf32(utf16, utf16 + 2, &character);
const std::array utf16 = {m_surrogate, static_cast<std::uint16_t>(character)};
sf::Utf16::toUtf32(utf16.begin(), utf16.end(), &character);
m_surrogate = 0;
}

View File

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

View File

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

View File

@ -28,6 +28,8 @@
////////////////////////////////////////////////////////////
#import <SFML/Window/macOS/NSImage+raw.h>
#include <array>
@implementation NSImage (raw)
+ (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)
{
NSUInteger pixel[4] = {pixels[0], pixels[1], pixels[2], pixels[3]};
[bitmap setPixel:pixel atX:x y:y];
std::array<NSUInteger, 4> pixel = {pixels[0], pixels[1], pixels[2], pixels[3]};
[bitmap setPixel:pixel.data() atX:x y:y];
}
}

View File

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

View File

@ -239,7 +239,7 @@ TEST_CASE("[Network] sf::Packet")
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);
}
@ -251,7 +251,7 @@ TEST_CASE("[Network] sf::Packet")
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);
}

View File

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

View File

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