Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ jobs:
matrix:
os: [macos-15, ubuntu-24.04, windows-latest]
type: [Debug, Release]
compiler: [cl, clang++, g++]
compiler: [cl, clang++, g++-14]
exclude:
- os: macos-15
compiler: cl
- os: macos-15
compiler: g++
compiler: clang++
- os: ubuntu-24.04
compiler: cl
- os: windows-latest
compiler: clang++
- os: windows-latest
compiler: g++
compiler: g++-14
steps:
- uses: actions/checkout@v5

Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
- uses: actions/checkout@v5

- name: CMake configure
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS=-fsanitize=address,undefined,leak -DCMAKE_EXE_LINKER_FLAGS=-fsanitize=address,undefined,leak
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_CXX_FLAGS=-fsanitize=address,undefined,leak -DCMAKE_EXE_LINKER_FLAGS=-fsanitize=address,undefined,leak

- name: CMake build
run: cmake --build build --parallel --target run-unit-test
Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
sudo apt install -y valgrind

- name: CMake configure
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14

- name: CMake build
run: cmake --build build --parallel --target unittest
Expand All @@ -136,14 +136,14 @@ jobs:
sudo apt install -y lcov

- name: CMake configure
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS=--coverage -DCMAKE_EXE_LINKER_FLAGS=--coverage
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_CXX_FLAGS=--coverage -DCMAKE_EXE_LINKER_FLAGS=--coverage

- name: CMake build
run: cmake --build build --parallel --target run-unit-test

- name: Generate coverage
run: |
lcov --directory build --capture --output-file coverage.info --ignore-errors mismatch
lcov --directory build --capture --gcov-tool gcov-14 --output-file coverage.info --ignore-errors mismatch
lcov --list coverage.info
lcov --extract coverage.info --output-file argparse.info *argparse.hpp
lcov --list argparse.info
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_include_directories(${PROJECT_NAME} INTERFACE include/)

target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_23)

if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
enable_testing()
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This is a C++ implementation of Python's `argparse` module. The aim is to cover

## Dependencies

C++ argparse is a header-only library, so its setup is minimal. It has no external dependencies and only uses STL. Since it uses `std::ranges` and some other features, it requires C++20 compiler and standard library.
C++ argparse is a header-only library, so its setup is minimal. It has no external dependencies and only uses STL. Since it uses `std::ranges` and some other features, it requires C++23 compiler and standard library. In case of need, [v3.1.0](https://github.com/kkarbowiak/cpp-argparse/releases/tag/v3.1.0) is the latest release that still compiles in C++20 mode.

C++ argparse uses CMake internally, but you don't have to. Just put the [argparse.hpp](https://github.com/kkarbowiak/cpp-argparse/releases/latest/download/argparse.hpp) header somewhere and point your build system to it.

Expand Down
44 changes: 16 additions & 28 deletions include/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@
#include <any>
#include <format>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <print>
#include <ranges>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <variant>
#include <vector>
#include <cstdlib>
Expand Down Expand Up @@ -91,12 +92,12 @@ namespace argparse

inline auto operator|(Handle lhs, Handle rhs) -> Handle
{
return static_cast<Handle>(static_cast<int>(lhs) | static_cast<int>(rhs));
return static_cast<Handle>(std::to_underlying(lhs) | std::to_underlying(rhs));
}

inline auto operator&(Handle lhs, Handle rhs) -> int
{
return static_cast<int>(lhs) & static_cast<int>(rhs);
return std::to_underlying(lhs) & std::to_underlying(rhs);
}

template<typename T>
Expand Down Expand Up @@ -256,7 +257,7 @@ namespace argparse
{
if (m_handle & Handle::help)
{
std::cout << format_help() << std::endl;
std::println("{}", format_help());
std::exit(EXIT_SUCCESS);
}

Expand All @@ -266,7 +267,7 @@ namespace argparse
{
if (m_handle & Handle::version)
{
std::cout << format_version() << std::endl;
std::println("{}", format_version());
std::exit(EXIT_SUCCESS);
}

Expand All @@ -276,8 +277,8 @@ namespace argparse
{
if (m_handle & Handle::errors)
{
std::cout << e.what() << '\n';
std::cout << format_help() << std::endl;
std::println("{}", e.what());
std::println("{}", format_help());
std::exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -394,19 +395,8 @@ namespace argparse

static auto join(std::ranges::view auto strings, std::string_view separator) -> std::string
{
auto result = std::string();

for (auto const & string : strings | std::views::take(1))
{
result += string;
}
for (auto const & string : strings | std::views::drop(1))
{
result += separator;
result += string;
}

return result;
auto const joined = std::ranges::fold_left_first(strings, [=](auto l, auto const & r) { l += separator; l += r; return std::move(l); });
return joined.value_or(std::string());
}

static auto parse_optional_arguments(std::ranges::view auto arguments, Tokens & tokens) -> void
Expand Down Expand Up @@ -578,9 +568,10 @@ namespace argparse

auto transform(std::vector<std::any> const & values) const -> std::any override
{
auto const transformation = values
| std::views::transform([](auto const & value) { return std::any_cast<T>(value); });
return std::any(std::vector(transformation.begin(), transformation.end()));
return std::any(
values
| std::views::transform([](auto const & value) { return std::any_cast<T>(value); })
| std::ranges::to<std::vector>());
}

auto append(std::any const & value, std::any & values) const -> void override
Expand Down Expand Up @@ -1353,7 +1344,7 @@ namespace argparse
{
if (name[1] != '-')
{
if (it->m_token.starts_with("-") && !it->m_token.starts_with("--") && it->m_token.find(name[1]) != std::string::npos)
if (it->m_token.starts_with("-") && !it->m_token.starts_with("--") && it->m_token.contains(name[1]))
{
return name;
}
Expand Down Expand Up @@ -1883,10 +1874,7 @@ namespace argparse

if (argument.has_nargs_number())
{
for (auto n = 0u; n < argument.get_nargs_number(); n++)
{
result += " " + formatted_arg;
}
result += std::ranges::fold_left(std::views::repeat(" " + formatted_arg, argument.get_nargs_number()), std::string(), std::plus());
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion test/exit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target_sources(app
PRIVATE
main.cpp)

target_compile_features(app PRIVATE cxx_std_20)
target_compile_features(app PRIVATE cxx_std_23)
target_compile_options(app PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wextra -Wmisleading-indentation -Wunused
Expand Down
2 changes: 1 addition & 1 deletion test/unittest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ target_link_libraries(unittest PRIVATE
cpp-argparse
doctest)

target_compile_features(unittest PRIVATE cxx_std_20)
target_compile_features(unittest PRIVATE cxx_std_23)
target_compile_options(unittest PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wextra -Wmisleading-indentation -Wunused
Expand Down
2 changes: 1 addition & 1 deletion tutorial/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ set(targets
foreach(target ${targets})
add_executable(${target})
target_sources(${target} PRIVATE ${target}.cpp)
target_compile_features(${target} PRIVATE cxx_std_20)
target_compile_features(${target} PRIVATE cxx_std_23)
target_compile_options(${target} PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wextra -Wmisleading-indentation -Wunused
Expand Down