diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml new file mode 100644 index 0000000..efd986a --- /dev/null +++ b/.github/workflows/ccpp.yml @@ -0,0 +1,58 @@ +name: C/C++ CI + +on: [push] + +jobs: + build-ubuntu: + + runs-on: ubuntu-latest + strategy: + matrix: + config: [Debug, Release] + standard: [11, 17] + + steps: + - uses: actions/checkout@v1 + - name: Build & Test + run: | + cmake -E remove_directory build + cmake -B build -S . -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DCMAKE_CXX_FLAGS="-Werror -fsanitize=address,undefined" + cmake --build build + cd build + ctest --output-on-failure + + build-windows: + + runs-on: windows-latest + strategy: + matrix: + config: [Release] + standard: [11, 17] + + steps: + - uses: actions/checkout@v1 + - name: Build & Test + run: | + cmake -E remove_directory build + cmake -B build -S . -DCMAKE_CXX_STANDARD=${{ matrix.standard }} # -DCMAKE_CXX_FLAGS="/WX" + cmake --build build --config ${{ matrix.config }} + cd build + ctest --output-on-failure + + build-macos: + + runs-on: macOS-latest + strategy: + matrix: + config: [Release] + standard: [11, 17] + + steps: + - uses: actions/checkout@v1 + - name: Build & Test + run: | + cmake -E remove_directory build + cmake -B build -S . -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DCMAKE_CXX_FLAGS="-Werror -fsanitize=address,undefined" + cmake --build build + cd build + ctest --output-on-failure \ No newline at end of file diff --git a/.gitignore b/.gitignore index f6b4931..1ad1abb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ -build +build/ +cmake-build-* +.vs/ +.vscode/ +.idea/ +.project *~ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..998cd4f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.5) + +project(TokenBucket VERSION 1.0 LANGUAGES CXX) + +add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + +target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11) + +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $) + +# Tests and examples +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + if (MSVC) + add_compile_options(/permissive- /W4 /wd4172 /wd4324 /wd4530) + else() + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + + add_executable(TokenBucketTest src/TokenBucketTest.cpp) + target_link_libraries(TokenBucketTest TokenBucket) + + enable_testing() + add_test(TokenBucketTest TokenBucketTest) +endif() + +# Install +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) + +export( + TARGETS ${PROJECT_NAME} + NAMESPACE ${PROJECT_NAME}:: + FILE "${PROJECT_NAME}Config.cmake" +) + +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + install( + DIRECTORY "include/" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + + install( + TARGETS ${PROJECT_NAME} + EXPORT "${PROJECT_NAME}Config" + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + + install( + EXPORT "${PROJECT_NAME}Config" + NAMESPACE ${PROJECT_NAME}:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + ) + + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + ) +endif() \ No newline at end of file diff --git a/TokenBucket.h b/include/rigtorp/TokenBucket.h similarity index 51% rename from TokenBucket.h rename to include/rigtorp/TokenBucket.h index 0594733..758b31d 100644 --- a/TokenBucket.h +++ b/include/rigtorp/TokenBucket.h @@ -1,11 +1,33 @@ -// © 2023 Erik Rigtorp -// SPDX-License-Identifier: MIT +/* +Copyright (c) 2023 Erik Rigtorp +SPDX-License-Identifier: MIT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ #pragma once #include #include +namespace rigtorp { + template class TokenBucket { public: TokenBucket() = default; @@ -44,3 +66,5 @@ template class TokenBucket { std::chrono::nanoseconds timePerToken_; std::chrono::nanoseconds timePerBurst_; }; + +}; \ No newline at end of file diff --git a/src/TokenBucketTest.cpp b/src/TokenBucketTest.cpp new file mode 100644 index 0000000..35dbdc8 --- /dev/null +++ b/src/TokenBucketTest.cpp @@ -0,0 +1,53 @@ +/* +Copyright (c) 2023 Erik Rigtorp +SPDX-License-Identifier: MIT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +int main() { + + using namespace rigtorp; + + { + TokenBucket<> tb(350, 1050); + + assert(tb.consume(1050)); + assert(!tb.consume(1)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + assert(tb.consume(350)); + assert(!tb.consume(1)); + } + + { + TokenBucket<> tb(350, 1050); + + assert(!tb.consume(1051)); + } + + return 0; +} \ No newline at end of file diff --git a/test.cpp b/test.cpp deleted file mode 100644 index ff2c063..0000000 --- a/test.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// © 2023 Erik Rigtorp -// SPDX-License-Identifier: MIT - -#include "TokenBucket.h" -#include -#include -#include - -int main(int arv, char *argv[]) { - - { - TokenBucket tb(350, 1050); - - assert(tb.consume(1050)); - assert(!tb.consume(1)); - sleep(1); - assert(tb.consume(350)); - assert(!tb.consume(1)); - } - - { - TokenBucket tb(350, 1050); - - assert(!tb.consume(1051)); - } - - return 0; -} \ No newline at end of file