diff --git a/.clang-tidy b/.clang-tidy index 7661b60..4ccb935 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,103 +1,90 @@ Checks: > - *, - -altera-id-dependent-backward-branch, - -altera-struct-pack-align, - -altera-unroll-loops, - -fuchsia-*, - -llvmlibc-*, - -llvm-header-guard, - -llvm-include-order, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-non-private-member-variables-in-classes, - -cppcoreguidelines-avoid-non-const-global-variables, - -cppcoreguidelines-avoid-magic-numbers, - -google-readability-todo, - -modernize-use-trailing-return-type, - -modernize-pass-by-value, - -misc-non-private-member-variables-in-classes, - -performance-avoid-endl, + -*, + bugprone-*, # Enable bug-prone checks + cppcoreguidelines-*, # Enable C++ Core Guidelines checks + modernize-*, # Enable modernization checks + readability-*, # Enable readability checks + performance-* # Enable performance checks -# Checks: > -# *, -# -cppcoreguidelines-owning-memory -# -google-readability-todo, -# -altera-unroll-loops, -# -altera-id-dependent-backward-branch, -# -altera-struct-pack-align, -# -fuchsia-*, -# fuchsia-multiple-inheritance, -# -llvm-header-guard, -# -llvm-include-order, -# -llvmlibc-*, -# -modernize-use-trailing-return-type, -# -misc-non-private-member-variables-in-classes, -# -cppcoreguidelines-pro-type-vararg, -# -cppcoreguidelines-avoid-c-arrays, -# -hicpp-vararg, -# -hicpp-avoid-c-arrays, -# -modernize-avoid-c-arrays +# Optionally, disable specific checks that are not relevant +# For example, if you don't use certain C++ features or have specific project constraints +# -*.fuchsia-* +# -*.llvmlibc-* +# -*.llvm-* -WarningsAsErrors: "" -# WarningsAsErrors: "*,-readability-convert-member-functions-to-static" +WarningsAsErrors: "*" CheckOptions: - - key: "readability-identifier-length.MinimumVariableNameLength" + # Identifier Length + - key: readability-identifier-length.MinimumVariableNameLength value: "2" - - key: "readability-identifier-length.MinimumParameterNameLength" + - key: readability-identifier-length.MinimumParameterNameLength value: "2" - - key: "readability-identifier-length.MinimumLoopCounterNameLength" + - key: readability-identifier-length.MinimumLoopCounterNameLength value: "2" - - { key: readability-identifier-naming.NamespaceCase, value: lower_case } + + # Naming Conventions + # Namespaces + - { key: readability-identifier-naming.NamespaceCase, value: snake_case } + + # Macros - { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE, } + + # Types - { key: readability-identifier-naming.ClassCase, value: CamelCase } - { key: readability-identifier-naming.StructCase, value: CamelCase } - { key: readability-identifier-naming.EnumCase, value: CamelCase } - - { key: readability-identifier-naming.EnumConstantCase, value: CamelCase } + - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE } - { key: readability-identifier-naming.TypedefCase, value: CamelCase } - { key: readability-identifier-naming.TypeAliasCase, value: CamelCase } - { key: readability-identifier-naming.UnionCase, value: CamelCase } - - { key: readability-identifier-naming.FunctionCase, value: lower_case } - - { key: readability-identifier-naming.GlobalFunctionCase, value: lower_case } + # Functions + - { key: readability-identifier-naming.FunctionCase, value: snake_case } + - { key: readability-identifier-naming.GlobalFunctionCase, value: snake_case } - - { key: readability-identifier-naming.GlobalVariableCase, value: CamelCase } + # Variables + - { key: readability-identifier-naming.GlobalVariableCase, value: snake_case } + - { key: readability-identifier-naming.LocalVariableCase, value: snake_case } + - { key: readability-identifier-naming.ParameterCase, value: snake_case } - - { key: readability-identifier-naming.LocalVariableCase, value: aNy_CasE } - - { key: readability-identifier-naming.ParameterCase, value: aNy_CasE } - #static - - { key: readability-identifier-naming.ClassMemberCase, value: lower_case } - - { key: readability-identifier-naming.ClassMethodCase, value: lower_case } + # Class Members and Methods + - { key: readability-identifier-naming.ClassMemberCase, value: snake_case_ } + - { key: readability-identifier-naming.ClassMethodCase, value: snake_case } - - { key: readability-identifier-naming.MethodCase, value: lower_case } - - { key: readability-identifier-naming.PrivateMethodCase, value: lower_case } + # General Methods + - { key: readability-identifier-naming.MethodCase, value: snake_case } + - { key: readability-identifier-naming.PrivateMethodCase, value: snake_case } - - { key: readability-identifier-naming.MemberCase, value: lower_case } - - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } + # Members + - { key: readability-identifier-naming.MemberCase, value: snake_case_ } + - { key: readability-identifier-naming.PrivateMemberCase, value: snake_case_ } - { key: readability-identifier-naming.PrivateMemberSuffix, value: "_" } - - { key: readability-identifier-naming.VariableCase, value: lower_case } - - - { key: readability-identifier-naming.StaticVariableCase, value: lower_case } + # Variables + - { key: readability-identifier-naming.VariableCase, value: snake_case } + - { key: readability-identifier-naming.StaticVariableCase, value: snake_case } - { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE, } - #constant - - { key: readability-identifier-naming.GlobalConstantCase, value: lower_case } - - { key: readability-identifier-naming.MemberConstantCase, value: lower_case } - - - { key: readability-identifier-naming.StaticConstantCase, value: lower_case } + # Constants + - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.MemberConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } + # Template Parameters - { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase, } - # some magic number + + # Magic Numbers - { key: readability-magic-numbers.IgnoredIntegerValues, - value: "-1; 0; 1; 2; 3; 4; 5;10;100", - } + value: "-1;0;1;2;3;4;5;10;100", +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b672eef --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: C++ CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake g++ make + + - name: Build + run: | + mkdir build && cd build + cmake .. + make + + - name: Run tests + run: | + cd build + ctest --output-on-failure + + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install clang-format + run: sudo apt-get install -y clang-format + + - name: Run clang-format + run: | + find src tests -name '*.cpp' -o -name '*.h' | xargs clang-format -i --style=file + git diff --exit-code + + clang-tidy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake g++ make clang-tidy + + - name: Generate compile_commands.json + run: | + mkdir build && cd build + cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. + + - name: Run clang-tidy + run: | + find src tests -name '*.cpp' -o -name '*.h' | xargs clang-tidy -p build \ No newline at end of file diff --git a/Makefile b/Makefile index f3ad5ce..b1ba350 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,11 @@ generate-ninja gn: generate-test gt: @$(MAKE) generate BUILD_TESTS=ON -format f: - fd "\.(h|cpp|hxx)$$" src -x clang-format -i +format: + find src tests -name '*.cpp' -o -name '*.h' | xargs clang-format -i --style=file + +lint: build + find src tests -name '*.cpp' -o -name '*.h' | xargs clang-tidy -p build docs: @echo "Generating documentation..." @@ -65,6 +68,7 @@ help h: @echo " all : Default target, builds the project." @echo " build (b) : Build the project with specified BUILD_TYPE (default: Release)." @echo " format (f) : Format the source code using clang-format." + @echo " lint : Run clang-tidy on the source code." @echo " test : Rebuild and run tests." @echo " run [path] : Rebuild and run the executable. Provide path to override default." @echo " clean : Remove the build directory." @@ -75,3 +79,4 @@ help h: @echo " generate-test (gt) : Generate the build system with tests." @echo " docs : Generate Doxygen documentation into $(DOCS_OUTPUT_DIR)." @echo " help : Show this help message." + diff --git a/TODO.md b/TODO.md index 5bd3230..3810b8b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,9 @@ # Random class -- [] Review all the unit tests +- [ ] Random unit tests # Project wide -- add gcov -- add CI/Coverage +- [ ] add gcov +- [ ] add CI/Coverage +- [ ] choose a logging library diff --git a/src/Core/Random/README.md b/src/Core/Random/README.md index 21831ec..cc67bdf 100644 --- a/src/Core/Random/README.md +++ b/src/Core/Random/README.md @@ -13,13 +13,41 @@ The `Random` class encapsulates random number generation functionalities using t - **Shuffling Capabilities:** Shuffle elements in an array using the current random generator. - **Resource Management:** Utilizes `std::unique_ptr` with a custom deleter to manage the GSL RNG resource. - **Seed Control:** Allows setting and retrieving the RNG seed for reproducibility. -- **Move Semantics:** Supports move construction and move assignment for flexible resource management. +- **Templated Methods:** Provides templated methods for generating uniformly and normally distributed random numbers with flexible types. ## Dependencies - [GNU Scientific Library (GSL)](https://www.gnu.org/software/gsl/) - [fmt](https://fmt.dev/) (Optional, used for formatting logs) +## Installation + +### Prerequisites + +Ensure that the following dependencies are installed on your system: + +- **GNU Scientific Library (GSL):** + ```bash + sudo apt-get install libgsl-dev + ``` +- **fmt Library:** (Optional, only if you intend to use logging features) + ```bash + sudo apt-get install libfmt-dev + ``` + +### Building the Project + +Assuming you're using CMake for your project, ensure that you link against GSL and fmt (if used): + +```cmake +find_package(GSL REQUIRED) +find_package(fmt REQUIRED) # Optional + +add_executable(your_executable main.cpp Random.cpp) +target_include_directories(your_executable PRIVATE ${GSL_INCLUDE_DIRS}) +target_link_libraries(your_executable PRIVATE ${GSL_LIBRARIES} fmt::fmt) # fmt is optional +``` + ## Usage ### Initialization @@ -51,7 +79,7 @@ int poisson_sample = rng.random_poisson(lambda); uint64_t uniform_int = rng.random_uniform(100); // Uniform integer in [50, 150) -uint64_t uniform_int_range = rng.random_uniform(50, 150); +uint64_t uniform_int_range = rng.random_uniform(50, 150); // Uniform double in [0.0, 1.0) double uniform_double = rng.random_uniform(); @@ -73,7 +101,7 @@ double normal_sample = rng.random_normal(mean, std_dev); double truncated_normal = rng.random_normal_truncated(mean, std_dev); // Normal integer -int normal_int = rng.random_normal(5, 2); +int normal_int = rng.random_normal(5, 2); // Truncated normal integer within ±3 standard deviations int truncated_normal_int = rng.random_normal_truncated(5, 2); @@ -147,11 +175,13 @@ rng.set_seed(123456789); ### Move Semantics +> **Note:** The `Random` class **does not** support move construction or move assignment. Both copy and move operations are deleted to ensure unique ownership of the RNG resource. + ```cpp Random rng1; -Random rng2 = std::move(rng1); // Move constructor -Random rng3; -rng3 = std::move(rng2); // Move assignment +// The following operations are **not** allowed and will result in a compile-time error +// Random rng2 = std::move(rng1); // Move constructor - Deleted +// rng2 = std::move(rng1); // Move assignment - Deleted ``` ## Example @@ -205,3 +235,22 @@ Contributions are welcome! Please fork the repository and submit a pull request - [GNU Scientific Library (GSL)](https://www.gnu.org/software/gsl/) - [fmt Library](https://fmt.dev/) + +--- + +### Changelog + +#### v1.1.0 + +- **Removed Move Semantics:** The `Random` class no longer supports move construction or move assignment to ensure unique ownership of the RNG resource. +- **Added Templated Methods:** Introduced templated methods `random_uniform` and `random_normal` for greater flexibility in generating random numbers of different types. +- **Updated Documentation:** Revised the README to accurately reflect the class's capabilities and limitations. +- **Dependency Clarifications:** Specified that the `fmt` library is optional and primarily used for logging purposes. + +#### v1.0.0 + +- Initial release with comprehensive random number generation functionalities using GSL. + +--- + +_This README was generated and updated by ChatGPT based on the provided `Random.cpp` and `Random.h` implementations._ diff --git a/src/Core/Random/Random.cpp b/src/Core/Random/Random.cpp index e3ad082..343b99a 100644 --- a/src/Core/Random/Random.cpp +++ b/src/Core/Random/Random.cpp @@ -73,29 +73,6 @@ uint64_t Random::random_uniform(uint64_t upper_bound) { return gsl_rng_uniform_int(rng_.get(), upper_bound); } -// Generates a uniform random integer in [from, to) -uint64_t Random::random_uniform(uint64_t lower_bound, uint64_t upper_bound) { - if (lower_bound >= upper_bound) { - throw std::invalid_argument("Parameter 'from' must be less than 'to'."); - } - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - return lower_bound - + gsl_rng_uniform_int(rng_.get(), upper_bound - lower_bound); -} - -// Generates a uniform random double in [from, to) -double Random::random_uniform(double from, double to) { - if (from >= to) { - throw std::invalid_argument("Parameter 'from' must be less than 'to'."); - } - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - return gsl_ran_flat(rng_.get(), from, to); -} - // Generates a uniform random double in [0, 1) double Random::random_uniform() { if (!rng_) { @@ -104,56 +81,6 @@ double Random::random_uniform() { return gsl_rng_uniform(rng_.get()); } -// Generates a normally distributed random double with given mean and standard -// deviation -double Random::random_normal(double mean, double standard_deviation) { - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - return mean + gsl_ran_gaussian(rng_.get(), standard_deviation); -} - -// Generates a normally distributed random integer with given mean and standard -// deviation -int Random::random_normal(int mean, int standard_deviation) { - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - return static_cast( - mean - + std::round(gsl_ran_gaussian(rng_.get(), - static_cast(standard_deviation)))); -} - -// Generates a truncated normally distributed random double within ±3 standard -// deviations -double Random::random_normal_truncated(double mean, double standard_deviation) { - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - double value = gsl_ran_gaussian(rng_.get(), standard_deviation); - while (std::abs(value) > TRUNCATION_LIMIT * standard_deviation) { - value = gsl_ran_gaussian(rng_.get(), standard_deviation); - } - return mean + value; -} - -// Generates a truncated normally distributed random integer within ±3 standard -// deviations -int Random::random_normal_truncated(int mean, int standard_deviation) { - if (!rng_) { - throw std::runtime_error("Random number generator not initialized."); - } - double value = - gsl_ran_gaussian(rng_.get(), static_cast(standard_deviation)); - while (std::abs(value) > TRUNCATION_LIMIT * standard_deviation) { - // Regenerate the value until it falls within the truncation limit - value = - gsl_ran_gaussian(rng_.get(), static_cast(standard_deviation)); - } - return static_cast(mean + std::round(value)); -} - // Generates a Beta-distributed random double double Random::random_beta(double alpha, double beta) { if (!rng_) { @@ -194,12 +121,6 @@ double Random::cdf_gamma_distribution_inverse(double probability, double alpha, return gsl_cdf_gamma_Pinv(probability, alpha, beta); } -// Generates a flat-distributed random double in [from, to) -double Random::random_flat(double from, double to) { - // This is identical to randomUniformDouble - return random_uniform(from, to); -} - // Generates multinomially distributed random numbers void Random::random_multinomial(std::size_t categories, unsigned trials, diff --git a/src/Core/Random/Random.h b/src/Core/Random/Random.h index 1a290a8..0bfe814 100644 --- a/src/Core/Random/Random.h +++ b/src/Core/Random/Random.h @@ -3,6 +3,7 @@ #ifndef RANDOM_H #define RANDOM_H +#include #include #include @@ -82,50 +83,96 @@ class Random { uint64_t random_uniform(uint64_t upper_bound); /** - * @brief Generates a uniform random integer in [lower_bound, upper_bound). + * @brief Generates a uniform random double in [0, 1). * - * @param lower_bound The inclusive lower bound. - * @param upper_bound The exclusive upper bound. - * @return uint64_t A uniformly distributed random integer. + * @return double A uniformly distributed random double. * - * @throws std::invalid_argument If lower_bound is not less than upper_bound. * @throws std::runtime_error If RNG is not initialized. */ - uint64_t random_uniform(uint64_t lower_bound, uint64_t upper_bound); + double random_uniform(); /** - * @brief Generates a uniform random double in [from, to). + * @brief Generates a uniformly distributed random number within a specified + * range. * - * @param from The inclusive lower bound. - * @param to The exclusive upper bound. - * @return double A uniformly distributed random double. + * This function returns a random number of type `T` that is uniformly + * distributed between the specified `from` and `to` values. The range is + * inclusive of `from` and exclusive of `to`. It supports both integral and + * floating-point types. * - * @throws std::invalid_argument If from is not less than to. - * @throws std::runtime_error If RNG is not initialized. - */ - double random_uniform(double from, double to); - - /** - * @brief Generates a uniform random double in [0, 1). + * @tparam T The numeric type of the random number to generate. Must be an + * arithmetic type. * - * @return double A uniformly distributed random double. + * @param from The lower bound of the range. Must be less than `to`. + * @param to The upper bound of the range. Must be greater than `from`. * - * @throws std::runtime_error If RNG is not initialized. + * @return A random number of type `T` uniformly distributed in [from, to). + * + * @throws std::runtime_error If the random number generator is not + * initialized. + * @throws std::invalid_argument If `from` is not less than `to`. + * + * @note Ensure that the random number generator (`rng_`) is properly + * initialized before invoking this function. */ - double random_uniform(); + template + T random_uniform(T from, T to) { + static_assert(std::is_arithmetic::value, + "Template parameter T must be numeric."); + + if (!rng_) { + throw std::runtime_error("Random number generator not initialized."); + } + + if (from >= to) { + throw std::invalid_argument("Parameter 'from' must be less than 'to'."); + } + + if constexpr (std::is_integral::value) { + // gsl_rng_uniform_int takes an unsigned long as upper bound + // Ensure that (to - from) does not exceed the maximum value of unsigned + // long + unsigned long range = static_cast(to - from); + // Note: gsl_rng_uniform_int handles range values up to the maximum of + // unsigned long + unsigned long value = gsl_rng_uniform_int(rng_.get(), range); + return static_cast(from + value); + } else { + double value = gsl_ran_flat(rng_.get(), static_cast(from), + static_cast(to)); + return static_cast(value); + } + } /** - * @brief Generates a normally distributed random double with given mean and + * @brief Generates a normally distributed random number with given mean and * standard deviation. * + * @tparam T The return type, typically `double` or `int`. * @param mean The mean of the normal distribution. * @param standard_deviation The standard deviation of the normal * distribution. - * @return double A random number following the normal distribution. + * @return T A random number following the normal distribution. * * @throws std::runtime_error If RNG is not initialized. */ - double random_normal(double mean, double standard_deviation); + template + T random_normal(T mean, double standard_deviation) { + static_assert(std::is_arithmetic::value, + "Template parameter T must be numeric."); + + if (!rng_) { + throw std::runtime_error("Random number generator not initialized."); + } + + double value = mean + gsl_ran_gaussian(rng_.get(), standard_deviation); + + if constexpr (std::is_integral::value) { + return static_cast(std::round(value)); + } else { + return static_cast(value); + } + } /** * @brief Generates a truncated normally distributed random double within ±3 @@ -134,37 +181,76 @@ class Random { * @param mean The mean of the normal distribution. * @param standard_deviation The standard deviation of the normal * distribution. + * @param truncation_limit The number of standard deviations to truncate. * @return double A truncated normally distributed random double. * * @throws std::runtime_error If RNG is not initialized. */ - double random_normal_truncated(double mean, double standard_deviation); + double random_normal_truncated(double mean, double standard_deviation, + double truncation_limit = 3.0); /** - * @brief Generates a normally distributed random integer with given mean and - * standard deviation. + * @brief Generates a truncated normally distributed random integer within ±3 + * standard deviations. * * @param mean The mean of the normal distribution. * @param standard_deviation The standard deviation of the normal * distribution. - * @return int A random integer following the normal distribution. + * @param truncation_limit The number of standard deviations to truncate. + * @return int A truncated normally distributed random integer. * * @throws std::runtime_error If RNG is not initialized. */ - int random_normal(int mean, int standard_deviation); + int random_normal_truncated(int mean, int standard_deviation, + double truncation_limit = 3.0); /** - * @brief Generates a truncated normally distributed random integer within ±3 - * standard deviations. + * @brief Generates a truncated normally distributed random number within a + * specified number of standard deviations. + * + * The function repeatedly generates normally distributed random numbers until + * one falls within the range [mean - truncation_limit * standard_deviation, + * mean + truncation_limit * standard_deviation]. To prevent potential + * infinite loops, a maximum number of attempts is enforced. * + * @tparam T The return type, typically `double` or `int`. * @param mean The mean of the normal distribution. * @param standard_deviation The standard deviation of the normal * distribution. - * @return int A truncated normally distributed random integer. - * - * @throws std::runtime_error If RNG is not initialized. + * @param truncation_limit The number of standard deviations to truncate + * (default is 3.0). + * @param max_attempts The maximum number of attempts to generate a valid + * truncated value (default is 1000). + * @return T A truncated normally distributed random number. + * + * @throws std::runtime_error If RNG is not initialized or if a valid + * truncated value cannot be generated within the maximum attempts. */ - int random_normal_truncated(int mean, int standard_deviation); + template + T random_normal_truncated(T mean, double standard_deviation, + double truncation_limit = 3.0, // NOLINT + int max_attempts = 1000) { + static_assert(std::is_arithmetic::value, + "Template parameter T must be numeric."); + if (!rng_) { + throw std::runtime_error("Random number generator not initialized."); + } + double value = gsl_ran_gaussian(rng_.get(), standard_deviation); + int attempts = 0; + while (std::abs(value) > truncation_limit * standard_deviation) { + if (attempts++ >= max_attempts) { + throw std::runtime_error( + "Failed to generate a truncated normal value within the maximum " + "number of attempts."); + } + value = gsl_ran_gaussian(rng_.get(), standard_deviation); + } + if constexpr (std::is_integral::value) { + return static_cast(mean + std::round(value)); + } else { + return static_cast(mean + value); + } + } /** * @brief Generates a Beta-distributed random double. @@ -214,17 +300,6 @@ class Random { double cdf_gamma_distribution_inverse(double probability, double alpha, double beta); - /** - * @brief Generates a flat-distributed random double in [from, to). - * - * This is identical to `random_uniform_double`. - * - * @param from The inclusive lower bound. - * @param to The exclusive upper bound. - * @return double A flat-distributed random double. - */ - double random_flat(double from, double to); - /** * @brief Generates multinomial random variables. * @@ -275,7 +350,6 @@ class Random { private: uint64_t seed_; - static constexpr double TRUNCATION_LIMIT = 3.0; // Custom deleter for gsl_rng struct GslRngDeleter { diff --git a/src/example.cpp b/src/example.cpp index 2c2cfd4..ee40869 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,5 +1,3 @@ #include "example.h" -int add(int a, int b) { - return a + b; -} +int add(int a, int b) { return a + b; } diff --git a/src/example.h b/src/example.h index a5c9692..ea0d292 100644 --- a/src/example.h +++ b/src/example.h @@ -3,4 +3,4 @@ int add(int a, int b); -#endif // EXAMPLE_H \ No newline at end of file +#endif // EXAMPLE_H diff --git a/tests/.clang-tidy b/tests/.clang-tidy index d27b977..33294fc 100644 --- a/tests/.clang-tidy +++ b/tests/.clang-tidy @@ -1,104 +1,89 @@ Checks: > - *, - -altera-id-dependent-backward-branch, - -altera-struct-pack-align, - -altera-unroll-loops, - -fuchsia-*, - -llvmlibc-*, - -llvm-header-guard, - -llvm-include-order, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-non-private-member-variables-in-classes, - -cppcoreguidelines-avoid-non-const-global-variables, - -cppcoreguidelines-avoid-magic-numbers, - -google-readability-todo, - -modernize-use-trailing-return-type, - -modernize-pass-by-value, - -misc-non-private-member-variables-in-classes, - -performance-avoid-endl, - -readability-magic-numbers + -*, + bugprone-*, # Enable bug-prone checks + cppcoreguidelines-*, # Enable C++ Core Guidelines checks + modernize-*, # Enable modernization checks + readability-*, # Enable readability checks + performance-* # Enable performance checks +# Optionally, disable specific checks that are not relevant +# For example, if you don't use certain C++ features or have specific project constraints +# -*.fuchsia-* +# -*.llvmlibc-* +# -*.llvm-* -# Checks: > -# *, -# -cppcoreguidelines-owning-memory -# -google-readability-todo, -# -altera-unroll-loops, -# -altera-id-dependent-backward-branch, -# -altera-struct-pack-align, -# -fuchsia-*, -# fuchsia-multiple-inheritance, -# -llvm-header-guard, -# -llvm-include-order, -# -llvmlibc-*, -# -modernize-use-trailing-return-type, -# -misc-non-private-member-variables-in-classes, -# -cppcoreguidelines-pro-type-vararg, -# -cppcoreguidelines-avoid-c-arrays, -# -hicpp-vararg, -# -hicpp-avoid-c-arrays, -# -modernize-avoid-c-arrays - -WarningsAsErrors: "" -# WarningsAsErrors: "*,-readability-convert-member-functions-to-static" +WarningsAsErrors: "*" CheckOptions: - - key: "readability-identifier-length.MinimumVariableNameLength" + # Identifier Length + - key: readability-identifier-length.MinimumVariableNameLength value: "2" - - key: "readability-identifier-length.MinimumParameterNameLength" + - key: readability-identifier-length.MinimumParameterNameLength value: "2" - - key: "readability-identifier-length.MinimumLoopCounterNameLength" + - key: readability-identifier-length.MinimumLoopCounterNameLength value: "2" - - { key: readability-identifier-naming.NamespaceCase, value: lower_case } + + # Naming Conventions + # Namespaces + - { key: readability-identifier-naming.NamespaceCase, value: snake_case } + + # Macros - { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE, } + + # Types - { key: readability-identifier-naming.ClassCase, value: CamelCase } - { key: readability-identifier-naming.StructCase, value: CamelCase } - { key: readability-identifier-naming.EnumCase, value: CamelCase } - - { key: readability-identifier-naming.EnumConstantCase, value: CamelCase } + - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE } - { key: readability-identifier-naming.TypedefCase, value: CamelCase } - { key: readability-identifier-naming.TypeAliasCase, value: CamelCase } - { key: readability-identifier-naming.UnionCase, value: CamelCase } - - { key: readability-identifier-naming.FunctionCase, value: lower_case } - - { key: readability-identifier-naming.GlobalFunctionCase, value: lower_case } + # Functions + - { key: readability-identifier-naming.FunctionCase, value: snake_case } + - { key: readability-identifier-naming.GlobalFunctionCase, value: snake_case } - - { key: readability-identifier-naming.GlobalVariableCase, value: CamelCase } + # Variables + - { key: readability-identifier-naming.GlobalVariableCase, value: snake_case } + - { key: readability-identifier-naming.LocalVariableCase, value: snake_case } + - { key: readability-identifier-naming.ParameterCase, value: snake_case } - - { key: readability-identifier-naming.LocalVariableCase, value: aNy_CasE } - - { key: readability-identifier-naming.ParameterCase, value: aNy_CasE } - #static - - { key: readability-identifier-naming.ClassMemberCase, value: lower_case } - - { key: readability-identifier-naming.ClassMethodCase, value: lower_case } + # Class Members and Methods + - { key: readability-identifier-naming.ClassMemberCase, value: snake_case_ } + - { key: readability-identifier-naming.ClassMethodCase, value: snake_case } - - { key: readability-identifier-naming.MethodCase, value: lower_case } - - { key: readability-identifier-naming.PrivateMethodCase, value: lower_case } + # General Methods + - { key: readability-identifier-naming.MethodCase, value: snake_case } + - { key: readability-identifier-naming.PrivateMethodCase, value: snake_case } - - { key: readability-identifier-naming.MemberCase, value: lower_case } - - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } + # Members + - { key: readability-identifier-naming.MemberCase, value: snake_case_ } + - { key: readability-identifier-naming.PrivateMemberCase, value: snake_case_ } - { key: readability-identifier-naming.PrivateMemberSuffix, value: "_" } - - { key: readability-identifier-naming.VariableCase, value: lower_case } - - - { key: readability-identifier-naming.StaticVariableCase, value: lower_case } + # Variables + - { key: readability-identifier-naming.VariableCase, value: snake_case } + - { key: readability-identifier-naming.StaticVariableCase, value: snake_case } - { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE, } - #constant - - { key: readability-identifier-naming.GlobalConstantCase, value: lower_case } - - - { key: readability-identifier-naming.MemberConstantCase, value: lower_case } - - { key: readability-identifier-naming.StaticConstantCase, value: lower_case } + # Constants + - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.MemberConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } + # Template Parameters - { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase, } - # some magic number + + # Magic Numbers - { key: readability-magic-numbers.IgnoredIntegerValues, - value: "-1; 0; 1; 2; 3; 4; 5;10;100", - } + value: "-1;0;1;2;3;4;5;10;100", +} diff --git a/tests/Core/Random/Random_test.cpp b/tests/Core/Random/Random_test.cpp index 804a0e6..8d90919 100644 --- a/tests/Core/Random/Random_test.cpp +++ b/tests/Core/Random/Random_test.cpp @@ -21,7 +21,7 @@ class RandomTest : public ::testing::Test { // Test default constructor initializes RNG TEST_F(RandomTest, DefaultConstructorInitializesRNG) { - Random rng; + Random const rng; EXPECT_NE(rng.get_seed(), 0); } @@ -157,10 +157,10 @@ TEST_F(RandomTest, RandomNormalInt) { // Check that the values are integers // Since the method returns int, this is implicit // Alternatively, check if they are within a reasonable range - EXPECT_GE(normal1, mean - 3 * std_dev); - EXPECT_LE(normal1, mean + 3 * std_dev); - EXPECT_GE(normal2, mean - 3 * std_dev); - EXPECT_LE(normal2, mean + 3 * std_dev); + EXPECT_GE(normal1, mean - (3 * std_dev)); + EXPECT_LE(normal1, mean + (3 * std_dev)); + EXPECT_GE(normal2, mean - (3 * std_dev)); + EXPECT_LE(normal2, mean + (3 * std_dev)); } // Test random_beta diff --git a/tests/example_test.cpp b/tests/example_test.cpp index a4f3501..cfd251a 100644 --- a/tests/example_test.cpp +++ b/tests/example_test.cpp @@ -1,10 +1,7 @@ -#include #include "example.h" -TEST(AdditionTest, PositiveNumbers) { - EXPECT_EQ(add(1, 2), 3); -} +#include + +TEST(AdditionTest, PositiveNumbers) { EXPECT_EQ(add(1, 2), 3); } -TEST(AdditionTest, NegativeNumbers) { - EXPECT_EQ(add(-1, -2), -3); -} \ No newline at end of file +TEST(AdditionTest, NegativeNumbers) { EXPECT_EQ(add(-1, -2), -3); }