From f0edf602f8b4574c65acc48bffc00e74959203c9 Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sun, 13 Jul 2025 15:29:09 -0400 Subject: [PATCH 1/3] Formatted everything with clang format based on WebKit. --- .clang-format | 11 + include/linear_congruential_generator.hpp | 12 +- include/mersenne_twister.hpp | 6 +- include/prng.hpp | 34 +-- include/program_runner.hpp | 72 ++--- include/xorshift.hpp | 23 +- src/main.cpp | 11 +- src/prngs/linear_congruential_generator.cpp | 71 +++-- src/prngs/mersenne_twister.cpp | 112 +++---- src/prngs/prng.cpp | 56 ++-- src/prngs/xorshift.cpp | 42 +-- src/runner.cpp | 322 ++++++++++---------- 12 files changed, 401 insertions(+), 371 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..495739c --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +--- +AlignEscapedNewlines: Left +BasedOnStyle: WebKit +BraceWrapping: + AfterFunction: true +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: true +BreakConstructorInitializers: BeforeComma +NamespaceIndentation: None +QualifierAlignment: Right +SpaceAfterTemplateKeyword: false diff --git a/include/linear_congruential_generator.hpp b/include/linear_congruential_generator.hpp index 6b5f614..583c15f 100644 --- a/include/linear_congruential_generator.hpp +++ b/include/linear_congruential_generator.hpp @@ -1,8 +1,8 @@ #ifndef LINEAR_CONGRUENTIAL_GENERATOR_H #define LINEAR_CONGRUENTIAL_GENERATOR_H -#include #include "prng.hpp" +#include class LinearCongruentialGenerator : public PseudoRandomNumberGenerator { // https://en.wikipedia.org/wiki/Linear_congruential_generator# @@ -15,11 +15,10 @@ class LinearCongruentialGenerator : public PseudoRandomNumberGenerator { a is the multiplier c is the increment - glibc uses m=2^{31} a=1103515245 c=12345 and masks the result with 0x3FFFFFFF + glibc uses m=2^{31} a=1103515245 c=12345 and masks the result with 0x3FFFFFFF which is what is used for the default implementation here */ private: - // Defaults used from the glibc implementation, see: /* @misc{ enwiki:1280426923, author = "{Wikipedia contributors}", @@ -29,17 +28,16 @@ class LinearCongruentialGenerator : public PseudoRandomNumberGenerator { note = "[Online; accessed 10-May-2025]" } */ - static constexpr uint64_t DefaultModulus = 0x7FFFFFFF; + static constexpr uint64_t DefaultModulus = 0x7FFFFFFF; static constexpr uint64_t DefaultMultiplier = 1103515245; static constexpr uint64_t DefaultIncrement = 12345; - static constexpr uint64_t DefaultMask = 0x7FFFFFFF; // bits 0 through 30 + static constexpr uint64_t DefaultMask = 0x7FFFFFFF; // bits 0 through 30 const uint64_t m_modulus; const uint64_t m_multiplier; const uint64_t m_increment; const uint64_t m_mask; - uint64_t m_current_value = 0; - + uint64_t m_current_value = 0; static uint64_t getMinimumValue(const std::uint64_t mask); static uint64_t getMaximumValue(const uint64_t modulus, const uint64_t mask); diff --git a/include/mersenne_twister.hpp b/include/mersenne_twister.hpp index 53627b0..cbeef74 100644 --- a/include/mersenne_twister.hpp +++ b/include/mersenne_twister.hpp @@ -1,14 +1,13 @@ #ifndef MERSENNE_TWISTER_H #define MERSENNE_TWISTER_H +#include "prng.hpp" #include #include -#include "prng.hpp" class MersenneTwister : public PseudoRandomNumberGenerator { private: - /* MT19937-64 coefficients: w = 64 , word size in bits n = 312, degree of recurrence @@ -45,7 +44,7 @@ class MersenneTwister : public PseudoRandomNumberGenerator { static constexpr uint64_t Default_c = 0xfff7eee000000000; static constexpr uint64_t Default_l = 43; static constexpr uint64_t Default_f = 6364136223846793005; - + // word size int m_w; @@ -89,7 +88,6 @@ class MersenneTwister : public PseudoRandomNumberGenerator { uint64_t m_lower_bit_mask; std::vector m_recurrence_state; int m_state_index = 0; - std::vector initializeRecurrenceState(const uint64_t seed) const; uint64_t generateNextStateValue(); diff --git a/include/prng.hpp b/include/prng.hpp index 5ab73eb..d37e524 100644 --- a/include/prng.hpp +++ b/include/prng.hpp @@ -3,27 +3,25 @@ #include -class PseudoRandomNumberGenerator -{ - protected: - const uint64_t m_seed; - const uint64_t m_minimum_value; - const uint64_t m_maximum_value; +class PseudoRandomNumberGenerator { +protected: + const uint64_t m_seed; + const uint64_t m_minimum_value; + const uint64_t m_maximum_value; +public: + PseudoRandomNumberGenerator(); + PseudoRandomNumberGenerator(const uint64_t seed); + PseudoRandomNumberGenerator(const uint64_t minimum_value, const uint64_t maximum_value); + PseudoRandomNumberGenerator(const uint64_t seed, const uint64_t minimum_value, const uint64_t maximum_value); + virtual ~PseudoRandomNumberGenerator() { } - public: - PseudoRandomNumberGenerator(); - PseudoRandomNumberGenerator(const uint64_t seed); - PseudoRandomNumberGenerator(const uint64_t minimum_value, const uint64_t maximum_value); - PseudoRandomNumberGenerator(const uint64_t seed, const uint64_t minimum_value, const uint64_t maximum_value); - virtual ~PseudoRandomNumberGenerator() {} + static uint64_t generateCryptographicallyInsecureSeed(); - static uint64_t generateCryptographicallyInsecureSeed(); - - virtual uint64_t generateRandomValue() = 0; - double generateUnitNormalRandomValue(); - double generateFloatingPointRandomValue(float min, float max); - int64_t generateIntegerRandomValue(int32_t min, int32_t max); + virtual uint64_t generateRandomValue() = 0; + double generateUnitNormalRandomValue(); + double generateFloatingPointRandomValue(float min, float max); + int64_t generateIntegerRandomValue(int32_t min, int32_t max); }; #endif \ No newline at end of file diff --git a/include/program_runner.hpp b/include/program_runner.hpp index b002f35..3f694d4 100644 --- a/include/program_runner.hpp +++ b/include/program_runner.hpp @@ -1,18 +1,18 @@ #ifndef PROGRAM_RUNNER_H #define PROGRAM_RUNNER_H +#include "prng.hpp" #include -#include #include -#include -#include +#include #include #include -#include "prng.hpp" +#include +#include -class ProgramRunner { +class ProgramRunner { public: - ProgramRunner(int argc, char **argv, uint64_t warmup_iterations = 0); + ProgramRunner(int argc, char** argv, uint64_t warmup_iterations = 0); struct ProgramStatus { std::optional stdout_message; @@ -33,12 +33,7 @@ class ProgramRunner { const std::string version = "0.1"; const std::string program_name = "randomizer"; - - - - private: - enum class Algorithm { XORShift, LinearCongruentialGenerator, @@ -47,17 +42,15 @@ class ProgramRunner { }; const std::map algorithm_choices { - {"xorshift", Algorithm::XORShift}, - {"xor", Algorithm::XORShift}, - {"linear-congruential-generator", Algorithm::LinearCongruentialGenerator}, - {"lcg", Algorithm::LinearCongruentialGenerator}, - {"mersenne", Algorithm::MersenneTwister}, - {"mersenne-twister", Algorithm::MersenneTwister}, - {"mt", Algorithm::MersenneTwister} + { "xorshift", Algorithm::XORShift }, + { "xor", Algorithm::XORShift }, + { "linear-congruential-generator", Algorithm::LinearCongruentialGenerator }, + { "lcg", Algorithm::LinearCongruentialGenerator }, + { "mersenne", Algorithm::MersenneTwister }, + { "mersenne-twister", Algorithm::MersenneTwister }, + { "mt", Algorithm::MersenneTwister } }; - - enum class ProgramBehaviour { Error, Help, @@ -68,16 +61,16 @@ class ProgramRunner { }; const std::map generation_types { - {"unit", ProgramBehaviour::GenerateUnitNormal}, - {"normal", ProgramBehaviour::GenerateUnitNormal}, - {"unit-normal", ProgramBehaviour::GenerateUnitNormal}, - {"normalized", ProgramBehaviour::GenerateUnitNormal}, - {"float", ProgramBehaviour::GenerateFloating}, - {"floating", ProgramBehaviour::GenerateFloating}, - {"decimal", ProgramBehaviour::GenerateFloating}, - {"floating-point", ProgramBehaviour::GenerateFloating}, - {"int", ProgramBehaviour::GenerateInteger}, - {"integer", ProgramBehaviour::GenerateInteger} + { "unit", ProgramBehaviour::GenerateUnitNormal }, + { "normal", ProgramBehaviour::GenerateUnitNormal }, + { "unit-normal", ProgramBehaviour::GenerateUnitNormal }, + { "normalized", ProgramBehaviour::GenerateUnitNormal }, + { "float", ProgramBehaviour::GenerateFloating }, + { "floating", ProgramBehaviour::GenerateFloating }, + { "decimal", ProgramBehaviour::GenerateFloating }, + { "floating-point", ProgramBehaviour::GenerateFloating }, + { "int", ProgramBehaviour::GenerateInteger }, + { "integer", ProgramBehaviour::GenerateInteger } }; struct RawArguments { @@ -96,23 +89,21 @@ class ProgramRunner { std::optional count_str; }; - // Defaults static constexpr uint32_t DefaultCount = 1; static constexpr ProgramBehaviour DefaultGenerationType = ProgramBehaviour::GenerateInteger; - static RawArguments parse_args(int argc, char **argv); - void determine_program_configuration(const RawArguments &raw_args); - void determine_user_message_configuration(const bool error, const bool show_version, const bool show_help); - void determine_generation_range_configuration(const std::optional &min_str, const std::optional &max_str); - void determine_generation_type_configuration(const std::optional &generation_type); - void determine_count_configuration(const std::optional &count_str); - void determine_algorithm_configuration(const std::optional &alg_str); + static RawArguments parse_args(int argc, char** argv); + void determine_program_configuration(RawArguments const& raw_args); + void determine_user_message_configuration(bool const error, bool const show_version, bool const show_help); + void determine_generation_range_configuration(std::optional const& min_str, std::optional const& max_str); + void determine_generation_type_configuration(std::optional const& generation_type); + void determine_count_configuration(std::optional const& count_str); + void determine_algorithm_configuration(std::optional const& alg_str); void create_prng(); void warmup(uint64_t iterations); - std::string error_string(); std::string help_string(); std::string version_string(); @@ -131,9 +122,6 @@ class ProgramRunner { // Exit codes static constexpr int ExitCodeSuccess = 0; static constexpr int ExitCodeError = 1; - - - }; #endif diff --git a/include/xorshift.hpp b/include/xorshift.hpp index b936e9c..1201335 100644 --- a/include/xorshift.hpp +++ b/include/xorshift.hpp @@ -1,23 +1,21 @@ #ifndef XOR_SHIFT_H #define XOR_SHIFT_H -#include #include "prng.hpp" +#include class XORShift : public PseudoRandomNumberGenerator { -// @misc{ enwiki:1287473197, -// author = "{Wikipedia contributors}", -// title = "Xorshift --- {Wikipedia}{,} The Free Encyclopedia", -// year = "2025", -// url = "https://en.wikipedia.org/w/index.php?title=Xorshift&oldid=1287473197", -// note = "[Online; accessed 11-May-2025]" -// } + // @misc{ enwiki:1287473197, + // author = "{Wikipedia contributors}", + // title = "Xorshift --- {Wikipedia}{,} The Free Encyclopedia", + // year = "2025", + // url = "https://en.wikipedia.org/w/index.php?title=Xorshift&oldid=1287473197", + // note = "[Online; accessed 11-May-2025]" + // } private: - - // Default values from https://en.wikipedia.org/wiki/Xorshift - static constexpr uint64_t DefaultA = 13; + static constexpr uint64_t DefaultA = 13; static constexpr uint64_t DefaultB = 7; static constexpr uint64_t DefaultC = 17; @@ -25,14 +23,13 @@ class XORShift : public PseudoRandomNumberGenerator { const uint64_t m_a; const uint64_t m_b; const uint64_t m_c; - uint64_t m_current_value = 0; + uint64_t m_current_value = 0; public: XORShift(); XORShift(const uint64_t seed); XORShift(const uint64_t seed, const uint64_t a, const uint64_t b, const uint64_t c); - uint64_t generateRandomValue() override; }; diff --git a/src/main.cpp b/src/main.cpp index 73b6635..0f1b122 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,12 @@ -#include -#include -#include "prng.hpp" #include "linear_congruential_generator.hpp" -#include "xorshift.hpp" +#include "prng.hpp" #include "program_runner.hpp" +#include "xorshift.hpp" +#include +#include -int main(int argc, char *argv[]){ +int main(int argc, char* argv[]) +{ ProgramRunner runner = ProgramRunner(argc, argv, 1000); ProgramRunner::ProgramStatus status; while (!runner.is_finished()) { diff --git a/src/prngs/linear_congruential_generator.cpp b/src/prngs/linear_congruential_generator.cpp index e405f90..dc09100 100644 --- a/src/prngs/linear_congruential_generator.cpp +++ b/src/prngs/linear_congruential_generator.cpp @@ -1,47 +1,54 @@ -#include -#include #include "linear_congruential_generator.hpp" #include "prng.hpp" - +#include +#include // Default constructor LinearCongruentialGenerator::LinearCongruentialGenerator() - : PseudoRandomNumberGenerator(getMinimumValue(DefaultMask), getMaximumValue(DefaultModulus, DefaultMask)), - m_modulus(DefaultModulus), - m_multiplier(DefaultMultiplier), - m_increment(DefaultIncrement), - m_mask(DefaultMask), - m_current_value(m_seed) {} + : PseudoRandomNumberGenerator(getMinimumValue(DefaultMask), getMaximumValue(DefaultModulus, DefaultMask)) + , m_modulus(DefaultModulus) + , m_multiplier(DefaultMultiplier) + , m_increment(DefaultIncrement) + , m_mask(DefaultMask) + , m_current_value(m_seed) +{ +} // Constructor with seed LinearCongruentialGenerator::LinearCongruentialGenerator(const uint64_t seed) - : PseudoRandomNumberGenerator(seed, getMinimumValue(DefaultMask), getMaximumValue(DefaultModulus, DefaultMask)), - m_modulus(DefaultModulus), - m_multiplier(DefaultMultiplier), - m_increment(DefaultIncrement), - m_mask(DefaultMask), - m_current_value(m_seed) {} + : PseudoRandomNumberGenerator(seed, getMinimumValue(DefaultMask), getMaximumValue(DefaultModulus, DefaultMask)) + , m_modulus(DefaultModulus) + , m_multiplier(DefaultMultiplier) + , m_increment(DefaultIncrement) + , m_mask(DefaultMask) + , m_current_value(m_seed) +{ +} // Constructor with custom parameters LinearCongruentialGenerator::LinearCongruentialGenerator(const uint64_t modulus, const uint64_t multiplier, const uint64_t increment, const uint64_t mask) - : PseudoRandomNumberGenerator(getMinimumValue(mask), getMaximumValue(modulus, mask)), - m_modulus(modulus), - m_multiplier(multiplier), - m_increment(increment), - m_mask(mask), - m_current_value(m_seed) {} + : PseudoRandomNumberGenerator(getMinimumValue(mask), getMaximumValue(modulus, mask)) + , m_modulus(modulus) + , m_multiplier(multiplier) + , m_increment(increment) + , m_mask(mask) + , m_current_value(m_seed) +{ +} // Constructor with seed and custom parameters LinearCongruentialGenerator::LinearCongruentialGenerator(const uint64_t seed, const uint64_t modulus, const uint64_t multiplier, const uint64_t increment, const uint64_t mask) - : PseudoRandomNumberGenerator(seed, getMinimumValue(mask), getMaximumValue(modulus, mask)), - m_modulus(modulus), - m_multiplier(multiplier), - m_increment(increment), - m_mask(mask), - m_current_value(m_seed) {} - + : PseudoRandomNumberGenerator(seed, getMinimumValue(mask), getMaximumValue(modulus, mask)) + , m_modulus(modulus) + , m_multiplier(multiplier) + , m_increment(increment) + , m_mask(mask) + , m_current_value(m_seed) +{ +} -uint64_t LinearCongruentialGenerator::getMinimumValue(const uint64_t mask) { +uint64_t LinearCongruentialGenerator::getMinimumValue(const uint64_t mask) +{ // Find the index of the least significant bit uint64_t least_significant_bit_index = 0; @@ -55,12 +62,14 @@ uint64_t LinearCongruentialGenerator::getMinimumValue(const uint64_t mask) { return (1 << least_significant_bit_index) - 1; } -uint64_t LinearCongruentialGenerator::getMaximumValue(const uint64_t modulus, const uint64_t mask) { +uint64_t LinearCongruentialGenerator::getMaximumValue(const uint64_t modulus, const uint64_t mask) +{ return std::min(modulus, mask); } // Generate a random value anywhere in the range of the LCG -uint64_t LinearCongruentialGenerator::generateRandomValue() { +uint64_t LinearCongruentialGenerator::generateRandomValue() +{ // Compute the standard LCG formula for the next value m_current_value = (m_multiplier * m_current_value + m_increment) % m_modulus; diff --git a/src/prngs/mersenne_twister.cpp b/src/prngs/mersenne_twister.cpp index 49a33d3..8be28f0 100644 --- a/src/prngs/mersenne_twister.cpp +++ b/src/prngs/mersenne_twister.cpp @@ -1,49 +1,52 @@ -#include +#include "mersenne_twister.hpp" +#include "prng.hpp" #include #include -#include "prng.hpp" -#include "mersenne_twister.hpp" - +#include MersenneTwister::MersenneTwister() - : m_w(Default_w), - m_n(Default_n), - m_m(Default_m), - m_r(Default_r), - m_a(Default_a), - m_u(Default_u), - m_d(Default_d), - m_s(Default_s), - m_b(Default_b), - m_t(Default_t), - m_c(Default_c), - m_l(Default_l), - m_f(Default_f), - m_upper_bit_mask(std::numeric_limits::max() << (m_r)), - m_lower_bit_mask(std::numeric_limits::max() >> (m_w - m_r)), - m_recurrence_state(initializeRecurrenceState(m_seed)) {} - + : m_w(Default_w) + , m_n(Default_n) + , m_m(Default_m) + , m_r(Default_r) + , m_a(Default_a) + , m_u(Default_u) + , m_d(Default_d) + , m_s(Default_s) + , m_b(Default_b) + , m_t(Default_t) + , m_c(Default_c) + , m_l(Default_l) + , m_f(Default_f) + , m_upper_bit_mask(std::numeric_limits::max() << (m_r)) + , m_lower_bit_mask(std::numeric_limits::max() >> (m_w - m_r)) + , m_recurrence_state(initializeRecurrenceState(m_seed)) +{ +} MersenneTwister::MersenneTwister(const uint64_t seed) - : PseudoRandomNumberGenerator(seed), - m_w(Default_w), - m_n(Default_n), - m_m(Default_m), - m_r(Default_r), - m_a(Default_a), - m_u(Default_u), - m_d(Default_d), - m_s(Default_s), - m_b(Default_b), - m_t(Default_t), - m_c(Default_c), - m_l(Default_l), - m_f(Default_f), - m_upper_bit_mask(std::numeric_limits::max() << (m_r)), - m_lower_bit_mask(std::numeric_limits::max() >> (m_w - m_r)), - m_recurrence_state(initializeRecurrenceState(m_seed)) {} - -std::vector MersenneTwister::initializeRecurrenceState(const uint64_t seed) const { + : PseudoRandomNumberGenerator(seed) + , m_w(Default_w) + , m_n(Default_n) + , m_m(Default_m) + , m_r(Default_r) + , m_a(Default_a) + , m_u(Default_u) + , m_d(Default_d) + , m_s(Default_s) + , m_b(Default_b) + , m_t(Default_t) + , m_c(Default_c) + , m_l(Default_l) + , m_f(Default_f) + , m_upper_bit_mask(std::numeric_limits::max() << (m_r)) + , m_lower_bit_mask(std::numeric_limits::max() >> (m_w - m_r)) + , m_recurrence_state(initializeRecurrenceState(m_seed)) +{ +} + +std::vector MersenneTwister::initializeRecurrenceState(const uint64_t seed) const +{ std::vector state(static_cast(m_n)); state[0] = seed; for (size_t i = 1; i < static_cast(m_n); ++i) { @@ -52,16 +55,17 @@ std::vector MersenneTwister::initializeRecurrenceState(const uint64_t return state; } -uint64_t MersenneTwister::generateNextStateValue(){ +uint64_t MersenneTwister::generateNextStateValue() +{ int k = m_state_index; // x_{k-n}, but since we are using circular indexing it is actually just the same as x_k! - int upper_index = k; - - // x_{k-(n-1)} + int upper_index = k; + + // x_{k-(n-1)} int lower_index = k - (m_n - 1); - if (lower_index < 0){ // wraparound the index for the buffer + if (lower_index < 0) { // wraparound the index for the buffer lower_index += m_n; } @@ -70,31 +74,30 @@ uint64_t MersenneTwister::generateNextStateValue(){ uint64_t concatenated_value = upper_part | lower_part; uint64_t matrix_mul_result = concatenated_value >> 1; - if ((concatenated_value & 0b1) == 0b1){ + if ((concatenated_value & 0b1) == 0b1) { matrix_mul_result ^= m_a; } - int middle_index = k - (m_n - m_m); - if (middle_index < 0){ + if (middle_index < 0) { middle_index += m_n; } uint64_t middle_value = m_recurrence_state[static_cast(middle_index)]; - uint64_t state_value = matrix_mul_result ^ middle_value; - + uint64_t state_value = matrix_mul_result ^ middle_value; + m_recurrence_state[static_cast(k)] = state_value; m_state_index++; - if (m_state_index >= m_n){ + if (m_state_index >= m_n) { m_state_index = 0; } return state_value; - } -uint64_t MersenneTwister::tempering(uint64_t val) const { +uint64_t MersenneTwister::tempering(uint64_t val) const +{ uint64_t tempered_value = val ^ (val >> m_u); tempered_value ^= ((tempered_value << m_s) & m_b); tempered_value ^= ((tempered_value << m_t) & m_c); @@ -102,7 +105,8 @@ uint64_t MersenneTwister::tempering(uint64_t val) const { return tempered_value; } -uint64_t MersenneTwister::generateRandomValue(){ +uint64_t MersenneTwister::generateRandomValue() +{ uint64_t raw_value = generateNextStateValue(); uint64_t tempered_value = tempering(raw_value); return tempered_value; diff --git a/src/prngs/prng.cpp b/src/prngs/prng.cpp index 44c5898..a652936 100644 --- a/src/prngs/prng.cpp +++ b/src/prngs/prng.cpp @@ -1,37 +1,44 @@ +#include "prng.hpp" #include #include -#include #include -#include "prng.hpp" +#include /* The most default constructor will create a random seed from the system time -and assume that the range of the PRNG is the full range of the unsigned 64-bit +and assume that the range of the PRNG is the full range of the unsigned 64-bit integer. While this is the only sensible default option, it is dangerous as it is not generally true and will likely have the PRNG produce highly incorrect values when generating uniform random floats. Use with caution! */ -PseudoRandomNumberGenerator::PseudoRandomNumberGenerator() - : m_seed(generateCryptographicallyInsecureSeed()), - m_minimum_value(std::numeric_limits::min()), - m_maximum_value(std::numeric_limits::max()) {} - +PseudoRandomNumberGenerator::PseudoRandomNumberGenerator() + : m_seed(generateCryptographicallyInsecureSeed()) + , m_minimum_value(std::numeric_limits::min()) + , m_maximum_value(std::numeric_limits::max()) +{ +} PseudoRandomNumberGenerator::PseudoRandomNumberGenerator(const uint64_t seed) - : m_seed(seed), - m_minimum_value(std::numeric_limits::min()), - m_maximum_value(std::numeric_limits::max()) {} + : m_seed(seed) + , m_minimum_value(std::numeric_limits::min()) + , m_maximum_value(std::numeric_limits::max()) +{ +} PseudoRandomNumberGenerator::PseudoRandomNumberGenerator(const uint64_t minimum_value, const uint64_t maximum_value) - : m_seed(generateCryptographicallyInsecureSeed()), - m_minimum_value(minimum_value), - m_maximum_value(maximum_value) {} - + : m_seed(generateCryptographicallyInsecureSeed()) + , m_minimum_value(minimum_value) + , m_maximum_value(maximum_value) +{ +} PseudoRandomNumberGenerator::PseudoRandomNumberGenerator(const uint64_t seed, const uint64_t minimum_value, const uint64_t maximum_value) - : m_seed(seed), - m_minimum_value(minimum_value), - m_maximum_value(maximum_value) {} + : m_seed(seed) + , m_minimum_value(minimum_value) + , m_maximum_value(maximum_value) +{ +} -std::uint64_t PseudoRandomNumberGenerator::generateCryptographicallyInsecureSeed() { +std::uint64_t PseudoRandomNumberGenerator::generateCryptographicallyInsecureSeed() +{ auto current_time = std::chrono::system_clock::now(); auto current_time_duration = current_time.time_since_epoch(); // convert a bare time to a duration auto time_as_milliseconds = std::chrono::duration_cast(current_time_duration); // get the duration as a value in milliseconds @@ -39,13 +46,15 @@ std::uint64_t PseudoRandomNumberGenerator::generateCryptographicallyInsecureSeed return seed_from_milliseconds; }; -double PseudoRandomNumberGenerator::generateFloatingPointRandomValue(float min, float max) { +double PseudoRandomNumberGenerator::generateFloatingPointRandomValue(float min, float max) +{ double random_val = generateUnitNormalRandomValue(); double scaled_value = min + (random_val * (max - min)); return scaled_value; } -int64_t PseudoRandomNumberGenerator::generateIntegerRandomValue(int32_t min, int32_t max) { +int64_t PseudoRandomNumberGenerator::generateIntegerRandomValue(int32_t min, int32_t max) +{ double random_val = generateUnitNormalRandomValue(); int64_t inclusive_range = max - min + 1; double random_val_magnitude = random_val * static_cast(inclusive_range); @@ -54,8 +63,9 @@ int64_t PseudoRandomNumberGenerator::generateIntegerRandomValue(int32_t min, int } // Generate a random value normalized to the range [0, 1) -double PseudoRandomNumberGenerator::generateUnitNormalRandomValue() { - +double PseudoRandomNumberGenerator::generateUnitNormalRandomValue() +{ + uint64_t random_value = generateRandomValue(); uint64_t range = m_maximum_value - m_minimum_value; diff --git a/src/prngs/xorshift.cpp b/src/prngs/xorshift.cpp index 9c01af8..ed99d1a 100644 --- a/src/prngs/xorshift.cpp +++ b/src/prngs/xorshift.cpp @@ -1,33 +1,37 @@ -#include #include "xorshift.hpp" #include "prng.hpp" - +#include // Default constructor XORShift::XORShift() - : m_a(DefaultA), - m_b(DefaultB), - m_c(DefaultC), - m_current_value(m_seed) {} + : m_a(DefaultA) + , m_b(DefaultB) + , m_c(DefaultC) + , m_current_value(m_seed) +{ +} XORShift::XORShift(const uint64_t seed) - : PseudoRandomNumberGenerator(seed), - m_a(DefaultA), - m_b(DefaultB), - m_c(DefaultC), - m_current_value(m_seed) {} + : PseudoRandomNumberGenerator(seed) + , m_a(DefaultA) + , m_b(DefaultB) + , m_c(DefaultC) + , m_current_value(m_seed) +{ +} XORShift::XORShift(const uint64_t seed, const uint64_t a, const uint64_t b, const uint64_t c) - : PseudoRandomNumberGenerator(seed), - m_a(a), - m_b(b), - m_c(c), - m_current_value(m_seed) {} - - + : PseudoRandomNumberGenerator(seed) + , m_a(a) + , m_b(b) + , m_c(c) + , m_current_value(m_seed) +{ +} // Generate a random value anywhere in the range of the XORShift algorithm -uint64_t XORShift::generateRandomValue() { +uint64_t XORShift::generateRandomValue() +{ // Compute the standard LCG formula for the next value m_current_value ^= (m_current_value << m_a); m_current_value ^= (m_current_value >> m_b); diff --git a/src/runner.cpp b/src/runner.cpp index ea925d3..0a9bf4e 100644 --- a/src/runner.cpp +++ b/src/runner.cpp @@ -1,25 +1,26 @@ -#include -#include +#include "linear_congruential_generator.hpp" +#include "mersenne_twister.hpp" +#include "prng.hpp" +#include "program_runner.hpp" +#include "xorshift.hpp" +#include +#include #include +#include +#include #include -#include -#include #include -#include -#include "program_runner.hpp" -#include "prng.hpp" -#include "xorshift.hpp" -#include "linear_congruential_generator.hpp" -#include "mersenne_twister.hpp" - +#include -std::string ProgramRunner::error_string() { - std::string error_string = program_name + ": bad usage\n" - + "Try '" + program_name + " --help' for more information."; +std::string ProgramRunner::error_string() +{ + std::string error_string = program_name + ": bad usage\n" + + "Try '" + program_name + " --help' for more information."; return error_string; } -std::string ProgramRunner::help_string() { +std::string ProgramRunner::help_string() +{ std::string help_string = "Usage: " + program_name + " [OPTIONS]\n\n" + "Options:\n" + " -a ALGORITHM, --algorithm=ALGORITHM Specify the algorithm [default: xorshift]\n" @@ -30,20 +31,21 @@ std::string ProgramRunner::help_string() { + " -h, --help Display this help and exit\n" + " -v, --version Output version information and exit"; return help_string; -} +} -std::string ProgramRunner::version_string() { +std::string ProgramRunner::version_string() +{ std::string version_string = program_name + " " + version; return version_string; } -template +template concept FromCharsParsable = std::is_integral_v || std::is_floating_point_v; - // Helper function for parsing a string to a numeric type using std::from_chars -template -std::optional parse_value(const std::string& str) { +template +std::optional parse_value(std::string const& str) +{ T value; auto result = std::from_chars(str.data(), str.data() + str.size(), value); if (result.ec != std::errc() || result.ptr != str.data() + str.size()) { @@ -52,37 +54,41 @@ std::optional parse_value(const std::string& str) { return value; } - -template -std::optional> parse_min_and_max_numbers(const std::string &min_str, const std::string &max_str) { +template +std::optional> parse_min_and_max_numbers(std::string const& min_str, std::string const& max_str) +{ std::optional min_value = parse_value(min_str); std::optional max_value = parse_value(max_str); - if (!min_value.has_value() || !max_value.has_value()) {return std::nullopt;} - if (min_value.value() <= max_value.value()) {return std::make_pair(min_value.value(), max_value.value());} + if (!min_value.has_value() || !max_value.has_value()) { + return std::nullopt; + } + if (min_value.value() <= max_value.value()) { + return std::make_pair(min_value.value(), max_value.value()); + } return std::nullopt; } - -void ProgramRunner::determine_generation_range_configuration(const std::optional &min_str, const std::optional &max_str){ +void ProgramRunner::determine_generation_range_configuration(std::optional const& min_str, std::optional const& max_str) +{ bool both_max_and_min_specified = min_str.has_value() && max_str.has_value(); bool neither_max_or_min_specified = !min_str.has_value() && !max_str.has_value(); - if (both_max_and_min_specified && this->behaviour == ProgramBehaviour::GenerateInteger){ + if (both_max_and_min_specified && this->behaviour == ProgramBehaviour::GenerateInteger) { auto min_and_max = parse_min_and_max_numbers(min_str.value(), max_str.value()); - if (!min_and_max.has_value()){ + if (!min_and_max.has_value()) { this->behaviour = ProgramBehaviour::Error; return; } this->min = min_and_max.value().first; this->max = min_and_max.value().second; - } else if (both_max_and_min_specified && this->behaviour == ProgramBehaviour::GenerateFloating){ + } else if (both_max_and_min_specified && this->behaviour == ProgramBehaviour::GenerateFloating) { auto min_and_max = parse_min_and_max_numbers(min_str.value(), max_str.value()); - if (!min_and_max.has_value()){ + if (!min_and_max.has_value()) { this->behaviour = ProgramBehaviour::Error; return; } this->min = min_and_max.value().first; this->max = min_and_max.value().second; - } else if (neither_max_or_min_specified && this->behaviour == ProgramBehaviour::GenerateUnitNormal){ + } else if (neither_max_or_min_specified && this->behaviour == ProgramBehaviour::GenerateUnitNormal) { return; } else { this->behaviour = ProgramBehaviour::Error; @@ -90,25 +96,27 @@ void ProgramRunner::determine_generation_range_configuration(const std::optional } } -void ProgramRunner::determine_user_message_configuration(const bool error, const bool show_version, const bool show_help){ - if (error){ +void ProgramRunner::determine_user_message_configuration(bool const error, bool const show_version, bool const show_help) +{ + if (error) { this->behaviour = ProgramBehaviour::Error; return; - } - - if (show_version){ + } + + if (show_version) { this->behaviour = ProgramBehaviour::Version; return; - } - - if (show_help){ + } + + if (show_help) { this->behaviour = ProgramBehaviour::Help; return; } } -void ProgramRunner::determine_algorithm_configuration(const std::optional &alg_str){ - if (!alg_str.has_value()){ +void ProgramRunner::determine_algorithm_configuration(std::optional const& alg_str) +{ + if (!alg_str.has_value()) { this->algorithm = Algorithm::XORShift; // default algorithm to use } else if (algorithm_choices.contains(alg_str.value())) { // TODO: this check/get can be made more efficient using find this->algorithm = algorithm_choices.at(alg_str.value()); @@ -117,20 +125,22 @@ void ProgramRunner::determine_algorithm_configuration(const std::optional &generation_type){ - if (!generation_type.has_value()){ +void ProgramRunner::determine_generation_type_configuration(std::optional const& generation_type) +{ + if (!generation_type.has_value()) { this->behaviour = DefaultGenerationType; - } else if (generation_types.contains(generation_type.value())){ + } else if (generation_types.contains(generation_type.value())) { this->behaviour = generation_types.at(generation_type.value()); } else { this->behaviour = ProgramBehaviour::Error; } } -void ProgramRunner::determine_count_configuration(const std::optional &count_str){ - if (count_str.has_value()){ +void ProgramRunner::determine_count_configuration(std::optional const& count_str) +{ + if (count_str.has_value()) { std::optional count_val = parse_value(count_str.value()); - if (!count_val.has_value() || count_val.value() <= 0){ + if (!count_val.has_value() || count_val.value() <= 0) { this->behaviour = ProgramBehaviour::Error; return; } @@ -140,44 +150,45 @@ void ProgramRunner::determine_count_configuration(const std::optionalbehaviour; - if (behave.has_value() && (behave == ProgramBehaviour::Error || behave == ProgramBehaviour::Version || behave == ProgramBehaviour::Help)){ + auto& behave = this->behaviour; + if (behave.has_value() && (behave == ProgramBehaviour::Error || behave == ProgramBehaviour::Version || behave == ProgramBehaviour::Help)) { return; } determine_algorithm_configuration(raw_args.algorithm_str); - if (behave.has_value() && behave == ProgramBehaviour::Error){ + if (behave.has_value() && behave == ProgramBehaviour::Error) { return; } determine_generation_type_configuration(raw_args.type); - if (behave.has_value() && behave == ProgramBehaviour::Error){ + if (behave.has_value() && behave == ProgramBehaviour::Error) { return; } determine_count_configuration(raw_args.count_str); - if (behave.has_value() && behave == ProgramBehaviour::Error){ + if (behave.has_value() && behave == ProgramBehaviour::Error) { return; } determine_generation_range_configuration(raw_args.min_str, raw_args.max_str); } -ProgramRunner::RawArguments ProgramRunner::parse_args(int argc, char **argv) { - const char* const short_opts = "+hva:m:M:c:t:"; +ProgramRunner::RawArguments ProgramRunner::parse_args(int argc, char** argv) +{ + char const* const short_opts = "+hva:m:M:c:t:"; const ::option long_opts[] = { // NOLINT (cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) - {"help", no_argument, nullptr, 'h'}, - {"version", no_argument, nullptr, 'v'}, - {"algorithm", required_argument, nullptr, 'a'}, - {"min", required_argument, nullptr, 'm'}, - {"max", required_argument, nullptr, 'M'}, - {"count", required_argument, nullptr, 'c'}, - {"type", required_argument, nullptr, 't'}, - {nullptr, 0, nullptr, 0} + { "help", no_argument, nullptr, 'h' }, + { "version", no_argument, nullptr, 'v' }, + { "algorithm", required_argument, nullptr, 'a' }, + { "min", required_argument, nullptr, 'm' }, + { "max", required_argument, nullptr, 'M' }, + { "count", required_argument, nullptr, 'c' }, + { "type", required_argument, nullptr, 't' }, + { nullptr, 0, nullptr, 0 } }; RawArguments raw_arguments; @@ -192,61 +203,62 @@ ProgramRunner::RawArguments ProgramRunner::parse_args(int argc, char **argv) { raw_arguments.type = std::nullopt; while (true) { - const auto opt = getopt_long(argc, argv, short_opts, long_opts, nullptr); // NOLINT (cppcoreguidelines-pro-bounds-array-to-pointer-decay) + auto const opt = getopt_long(argc, argv, short_opts, long_opts, nullptr); // NOLINT (cppcoreguidelines-pro-bounds-array-to-pointer-decay) - if (opt == -1){ + if (opt == -1) { break; } switch (opt) { - case 'h': - raw_arguments.show_help = true; - break; - case 'v': - raw_arguments.show_version = true; - break; - case 'a': - raw_arguments.algorithm_str = std::string(optarg); - break; - case 'm': - raw_arguments.min_str = std::string(optarg); - break; - case 'M': - raw_arguments.max_str = std::string(optarg); - break; - case 'c': - raw_arguments.count_str = std::string(optarg); - break; - case 't': - raw_arguments.type = std::string(optarg); - break; - default: - raw_arguments.error = true; - return raw_arguments; + case 'h': + raw_arguments.show_help = true; + break; + case 'v': + raw_arguments.show_version = true; + break; + case 'a': + raw_arguments.algorithm_str = std::string(optarg); + break; + case 'm': + raw_arguments.min_str = std::string(optarg); + break; + case 'M': + raw_arguments.max_str = std::string(optarg); + break; + case 'c': + raw_arguments.count_str = std::string(optarg); + break; + case 't': + raw_arguments.type = std::string(optarg); + break; + default: + raw_arguments.error = true; + return raw_arguments; } } return raw_arguments; } -void ProgramRunner::create_prng() { +void ProgramRunner::create_prng() +{ if (!this->algorithm.has_value()) { throw std::runtime_error("Algorithm not set, cannot create PseudoRandomNumberGenerator instance"); } switch (this->algorithm.value()) { - case ProgramRunner::Algorithm::XORShift: - this->prng = std::make_unique(); - break; - case ProgramRunner::Algorithm::LinearCongruentialGenerator: - this->prng = std::make_unique(); - break; - case ProgramRunner::Algorithm::MersenneTwister: - this->prng = std::make_unique(); - break; - default: - throw std::runtime_error("Unsupported algorithm"); + case ProgramRunner::Algorithm::XORShift: + this->prng = std::make_unique(); + break; + case ProgramRunner::Algorithm::LinearCongruentialGenerator: + this->prng = std::make_unique(); + break; + case ProgramRunner::Algorithm::MersenneTwister: + this->prng = std::make_unique(); + break; + default: + throw std::runtime_error("Unsupported algorithm"); } if (this->prng == nullptr) { @@ -254,30 +266,32 @@ void ProgramRunner::create_prng() { } } -ProgramRunner::ProgramRunner(int argc, char **argv, uint64_t warmup_iterations){ +ProgramRunner::ProgramRunner(int argc, char** argv, uint64_t warmup_iterations) +{ RawArguments raw_arguments = parse_args(argc, argv); determine_program_configuration(raw_arguments); if (this->algorithm.has_value()) { create_prng(); warmup(warmup_iterations); } - } -bool ProgramRunner::is_finished() { +bool ProgramRunner::is_finished() +{ if (this->finished) { return true; - } - + } + if ((this->count.has_value()) && (this->iteration >= this->count)) { this->finished = true; return true; - } + } return false; } -ProgramRunner::ProgramStatus ProgramRunner::iterate() { +ProgramRunner::ProgramStatus ProgramRunner::iterate() +{ if (is_finished()) { throw std::runtime_error("ProgramRunner has finished, cannot iterate further"); @@ -287,56 +301,54 @@ ProgramRunner::ProgramStatus ProgramRunner::iterate() { throw std::runtime_error("ProgramRunner not configured properly"); } - switch (this->behaviour.value()) { - case ProgramBehaviour::Error: - this->finished = true; - return {std::nullopt, error_string(), ProgramRunner::ExitCodeError}; + case ProgramBehaviour::Error: + this->finished = true; + return { std::nullopt, error_string(), ProgramRunner::ExitCodeError }; - case ProgramBehaviour::Help: - this->finished = true; - return {help_string(), std::nullopt, ProgramRunner::ExitCodeSuccess}; + case ProgramBehaviour::Help: + this->finished = true; + return { help_string(), std::nullopt, ProgramRunner::ExitCodeSuccess }; - case ProgramBehaviour::Version: - this->finished = true; - return {version_string(), std::nullopt, ProgramRunner::ExitCodeSuccess}; + case ProgramBehaviour::Version: + this->finished = true; + return { version_string(), std::nullopt, ProgramRunner::ExitCodeSuccess }; - case ProgramBehaviour::GenerateUnitNormal: { - this->iteration++; - double random_value = this->prng->generateUnitNormalRandomValue(); - auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; - return {std::to_string(random_value), std::nullopt, exit_code_based_on_count}; - } - - case ProgramBehaviour::GenerateFloating: { - this->iteration++; - double random_float = this->prng->generateFloatingPointRandomValue( - std::get(this->min.value_or(0.0F)), - std::get(this->max.value_or(1.0F)) - ); - auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; - return {std::to_string(random_float), std::nullopt, exit_code_based_on_count}; - } + case ProgramBehaviour::GenerateUnitNormal: { + this->iteration++; + double random_value = this->prng->generateUnitNormalRandomValue(); + auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; + return { std::to_string(random_value), std::nullopt, exit_code_based_on_count }; + } - case ProgramBehaviour::GenerateInteger: { - this->iteration++; - int64_t random_int = this->prng->generateIntegerRandomValue( - std::get(this->min.value_or(0)), - std::get(this->max.value_or(1)) - ); - auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; - return {std::to_string(random_int), std::nullopt, exit_code_based_on_count}; - } + case ProgramBehaviour::GenerateFloating: { + this->iteration++; + double random_float = this->prng->generateFloatingPointRandomValue( + std::get(this->min.value_or(0.0F)), + std::get(this->max.value_or(1.0F))); + auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; + return { std::to_string(random_float), std::nullopt, exit_code_based_on_count }; + } - default: - throw std::runtime_error("ProgramRunner not configured properly, behaviour is not set"); + case ProgramBehaviour::GenerateInteger: { + this->iteration++; + int64_t random_int = this->prng->generateIntegerRandomValue( + std::get(this->min.value_or(0)), + std::get(this->max.value_or(1))); + auto exit_code_based_on_count = is_finished() ? std::optional(ProgramRunner::ExitCodeSuccess) : std::nullopt; + return { std::to_string(random_int), std::nullopt, exit_code_based_on_count }; } - return {std::nullopt, std::nullopt, ProgramRunner::ExitCodeError}; // Should never reach here + default: + throw std::runtime_error("ProgramRunner not configured properly, behaviour is not set"); + } + + return { std::nullopt, std::nullopt, ProgramRunner::ExitCodeError }; // Should never reach here } -ProgramRunner::ProgramStatus ProgramRunner::iterate(uint64_t iterations) { +ProgramRunner::ProgramStatus ProgramRunner::iterate(uint64_t iterations) +{ if (iterations == 0) { throw std::invalid_argument("Number of iterations must be greater than zero"); } @@ -351,17 +363,19 @@ ProgramRunner::ProgramStatus ProgramRunner::iterate(uint64_t iterations) { return last_status; // Return the status of the last iteration } -ProgramRunner::ProgramStatus ProgramRunner::run() { +ProgramRunner::ProgramStatus ProgramRunner::run() +{ while (!is_finished()) { auto status = iterate(); if (status.exit_code.has_value()) { - return status; + return status; } } throw std::runtime_error("ProgramRunner has finished without returning an exit code. This should not happen."); } -void ProgramRunner::warmup(uint64_t iterations) { +void ProgramRunner::warmup(uint64_t iterations) +{ if (this->prng == nullptr) { throw std::runtime_error("PRNG is not initialized, cannot warmup"); } @@ -370,5 +384,3 @@ void ProgramRunner::warmup(uint64_t iterations) { this->prng->generateRandomValue(); // Warmup the PRNG } } - - From f418718e09d4a25da8130af238a226e18353ba2a Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sun, 13 Jul 2025 15:36:38 -0400 Subject: [PATCH 2/3] Added clang-format to CI. --- .clang-format | 2 +- .github/workflows/{testing.yml => jobs.yml} | 17 +++++++++++++++-- src/runner.cpp | 6 +++--- 3 files changed, 19 insertions(+), 6 deletions(-) rename .github/workflows/{testing.yml => jobs.yml} (75%) diff --git a/.clang-format b/.clang-format index 495739c..19ee2b3 100644 --- a/.clang-format +++ b/.clang-format @@ -8,4 +8,4 @@ BreakBeforeInheritanceComma: true BreakConstructorInitializers: BeforeComma NamespaceIndentation: None QualifierAlignment: Right -SpaceAfterTemplateKeyword: false +# find include src \( -name '*.cpp' -o -name '*.hpp' \) -exec clang-format -i {} + diff --git a/.github/workflows/testing.yml b/.github/workflows/jobs.yml similarity index 75% rename from .github/workflows/testing.yml rename to .github/workflows/jobs.yml index 098bcc7..8df7886 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/jobs.yml @@ -1,4 +1,4 @@ -name: Test and Lint +name: Jobs on: push: @@ -45,6 +45,19 @@ jobs: - name: run-tests run: ctest --test-dir build --output-on-failure + format: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install clang-format + run: sudo apt update && sudo apt-get install -y clang clang-format + + - name: Run clang-format + run: find include src \( -name '*.cpp' -o -name '*.hpp' \) -exec clang-format --dry-run --Werror {} + + lint: needs: build runs-on: ubuntu-latest @@ -58,7 +71,7 @@ jobs: name: built path: ./build - - name: Get clang-tidy + - name: Install clang-tidy run: sudo apt-get update && sudo apt-get install -y cmake clang clang-tidy g++ - name: lint diff --git a/src/runner.cpp b/src/runner.cpp index 0a9bf4e..f6d0635 100644 --- a/src/runner.cpp +++ b/src/runner.cpp @@ -39,11 +39,11 @@ std::string ProgramRunner::version_string() return version_string; } -template +template concept FromCharsParsable = std::is_integral_v || std::is_floating_point_v; // Helper function for parsing a string to a numeric type using std::from_chars -template +template std::optional parse_value(std::string const& str) { T value; @@ -54,7 +54,7 @@ std::optional parse_value(std::string const& str) return value; } -template +template std::optional> parse_min_and_max_numbers(std::string const& min_str, std::string const& max_str) { std::optional min_value = parse_value(min_str); From 5686907b7d0ea85eb71ef9a62432401358e5a83b Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sun, 13 Jul 2025 15:44:13 -0400 Subject: [PATCH 3/3] Pinned clang-format version used in CI to 14. --- .github/workflows/jobs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/jobs.yml b/.github/workflows/jobs.yml index 8df7886..0508312 100644 --- a/.github/workflows/jobs.yml +++ b/.github/workflows/jobs.yml @@ -53,10 +53,10 @@ jobs: uses: actions/checkout@v3 - name: Install clang-format - run: sudo apt update && sudo apt-get install -y clang clang-format + run: sudo apt update && sudo apt-get install -y clang clang-format-14 - name: Run clang-format - run: find include src \( -name '*.cpp' -o -name '*.hpp' \) -exec clang-format --dry-run --Werror {} + + run: find include src \( -name '*.cpp' -o -name '*.hpp' \) -exec clang-format-14 --dry-run --Werror {} + lint: needs: build