diff --git a/.circleci/config.yml b/.circleci/config.yml index 27c51e3..2d05ee2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,15 +6,15 @@ jobs: docker: - image: ubuntu:lunar environment: - CC: /usr/bin/gcc-13 - CXX: /usr/bin/g++-13 + CC: /usr/bin/gcc-12 + CXX: /usr/bin/g++-12 steps: - checkout - run: name: Install dependencies command: | apt-get update - apt-get install -y git curl libcurl4-openssl-dev cmake clang-format g++-13 + apt-get install -y git curl libcurl4-openssl-dev cmake clang-format g++-12 - run: name: Check clang-format command: | diff --git a/CMakeLists.txt b/CMakeLists.txt index f8c73e5..2fe063f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25) project(nanomath LANGUAGES C CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 20) include(FetchContent) FetchContent_Declare(argparse GIT_REPOSITORY https://github.com/p-ranav/argparse.git) @@ -12,11 +12,13 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) option(USE_SYSTEM_TZ_DB "Use OS timezone database" ON) set(BUILD_TZ_LIB ON) FetchContent_MakeAvailable(date) +FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG 10.2.1) +FetchContent_MakeAvailable(fmt) add_executable(nanomath src/nanomath.cpp) target_compile_options(nanomath PRIVATE -Wall -Wpedantic -Wextra -O3) -target_compile_features(nanomath PUBLIC cxx_std_23) -target_link_libraries(nanomath PRIVATE argparse date-tz) +target_compile_features(nanomath PUBLIC cxx_std_20) +target_link_libraries(nanomath PRIVATE argparse date-tz fmt::fmt) install(TARGETS nanomath) if (BUILD_TESTS) @@ -24,9 +26,9 @@ if (BUILD_TESTS) FetchContent_MakeAvailable(googletest) enable_testing() add_executable(nanomath_test test/nanomath.cpp) - target_link_libraries(nanomath_test GTest::gtest_main GTest::gmock date-tz) + target_link_libraries(nanomath_test GTest::gtest_main GTest::gmock date-tz fmt::fmt) target_include_directories(nanomath_test PRIVATE src) - target_compile_features(nanomath_test PRIVATE cxx_std_23) + target_compile_features(nanomath_test PRIVATE cxx_std_20) include(GoogleTest) gtest_discover_tests(nanomath_test) endif() diff --git a/README.md b/README.md index f516cc2..eb1e82b 100644 --- a/README.md +++ b/README.md @@ -20,16 +20,15 @@ nanomath --format m '2008-11-12T00:00:00Z - 2004-11-23T12:30:00Z' # 2087250m :wrench: *nanomath* is currently under active development. -## Build +## Download ```bash -git clone https://github.com/zdryan/nanomath -cd nanomath -cmake -S . -B build -make -C build +wget https://github.com/zdryan/nanomath/releases/download/v2024.02.01/nanomath-v2024.02.01-linux.tar.bz2 +tar -xf nanomath-v2024.02.01-linux.tar.bz2 ``` -## Install +## Build & Install (Linux) ```bash +git clone https://github.com/zdryan/nanomath cd nanomath -cmake --install build +cmake --build . --target install ``` diff --git a/src/nanomath.cpp b/src/nanomath.cpp index ee38200..9a2ebcb 100644 --- a/src/nanomath.cpp +++ b/src/nanomath.cpp @@ -30,12 +30,7 @@ int main(int argc, char *argv[]) else std::cout << nanomath::format(ns) << std::endl; } - catch (const std::format_error &err) - { - std::cerr << err.what() << std::endl; - return EXIT_FAILURE; - } - catch (const std::runtime_error &err) + catch (const std::exception &err) { std::cerr << err.what() << std::endl; return EXIT_FAILURE; diff --git a/src/nanomath.hpp b/src/nanomath.hpp index cdd498c..6408b60 100644 --- a/src/nanomath.hpp +++ b/src/nanomath.hpp @@ -2,10 +2,11 @@ #include "date/date.h" #include "date/tz.h" +#include "fmt/chrono.h" +#include "fmt/format.h" #include #include #include -#include #include #include #include @@ -63,7 +64,8 @@ inline Unit string_to_unit(std::string_view unit) // clang-format on if (units.contains(unit)) return units.at(unit); - throw std::format_error(std::format("unknown unit: '[{}]'", unit)); + throw std::runtime_error(fmt::format("unknown unit: '[{}]'", unit)); + __builtin_unreachable(); } inline constexpr int64_t factor(Unit unit) @@ -98,15 +100,16 @@ template inline std::string format(double count, std::string_ { double int_count; if (std::modf(count, &int_count) != 0) - return std::format("{:.2f}{}", count, unit); + return fmt::format("{:.2f}{}", count, unit); else - return std::format("{}{}", static_cast(count), unit); + return fmt::format("{}{}", static_cast(count), unit); } inline std::string format(const std::chrono::nanoseconds &nanos) { const auto time_point = std::chrono::sys_time(nanos); - return std::format("{:%Y-%m-%dT%H:%M:%S}Z", std::chrono::time_point_cast(time_point)); + return fmt::format("{:%Y-%m-%dT%H:%M:%S}Z", + fmt::gmtime(std::chrono::time_point_cast(time_point))); } inline std::string format(const std::chrono::nanoseconds &nanos, Unit unit) @@ -115,7 +118,7 @@ inline std::string format(const std::chrono::nanoseconds &nanos, Unit unit) switch (unit) { case Unit::NANOSECONDS: - return std::format("{}ns", nanos.count()); + return fmt::format("{}ns", nanos.count()); case Unit::MICROSECONDS: return format(nanos.count() / static_cast(MICROSECONDS), "us"); case Unit::MILLISECONDS: @@ -192,18 +195,18 @@ inline std::string replace(std::string_view input) } else { - throw std::format_error(std::format("invalid timezone designator: '{}'", designator)); + throw std::runtime_error(fmt::format("invalid timezone designator: '{}'", designator)); } result.append(oss.str()); const auto match_len = match.length(0); last_pos = pos + match_len; if (pos > 0 && std::isdigit(input[pos - 1])) - throw std::format_error( - std::format("invalid leading date time character: '[{}]{}'", input[pos - 1], match.str())); + throw std::runtime_error( + fmt::format("invalid leading date time character: '[{}]{}'", input[pos - 1], match.str())); if (static_cast(last_pos) < input.length() && std::isdigit(input[last_pos])) - throw std::format_error( - std::format("invalid trailing date time character: '{}[{}]'", match.str(), input[last_pos])); + throw std::runtime_error( + fmt::format("invalid trailing date time character: '{}[{}]'", match.str(), input[last_pos])); match_end = match_begin; std::advance(match_end, match_len); @@ -287,7 +290,7 @@ inline std::chrono::nanoseconds parse(std::string_view expression) } else { - throw std::format_error(std::format("invalid expression: '{}'", expression)); + throw std::runtime_error(fmt::format("invalid expression: '{}'", expression)); } } diff --git a/test/nanomath.cpp b/test/nanomath.cpp index 87abcbb..00099cb 100644 --- a/test/nanomath.cpp +++ b/test/nanomath.cpp @@ -64,7 +64,7 @@ TEST_F(NanoMathTest, parenthesized_duration_arithmetic) TEST_F(NanoMathTest, invalid_specifier) { - EXPECT_THROW(parse("1z"), std::format_error); + EXPECT_THROW(parse("1z"), std::runtime_error); } TEST_F(NanoMathTest, default_timezone_designator)