From fee3152ad375b790e45a530741c8549dbc6084c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 19 Sep 2024 21:53:47 -0600 Subject: [PATCH 01/16] Add initial implementation of `std::dump` --- .ci/docker/rockylinux.Dockerfile | 4 +- .github/CODEOWNERS | 2 +- CMakeLists.txt | 7 +- README.md | 214 +++--------------- examples/CMakeLists.txt | 11 +- examples/basic.cpp | 9 + examples/identity_as_default_projection.cpp | 87 ------- examples/identity_direct_usage.cpp | 10 - include/beman/dump/dump.hpp | 40 ++++ include/beman/example/identity.hpp | 48 ---- src/beman/dump/CMakeLists.txt | 35 +++ .../{example/identity.cpp => dump/dump.cpp} | 3 +- src/beman/dump/dump.t.cpp | 17 ++ src/beman/example/CMakeLists.txt | 32 --- src/beman/example/identity.t.cpp | 61 ----- 15 files changed, 138 insertions(+), 442 deletions(-) create mode 100644 examples/basic.cpp delete mode 100644 examples/identity_as_default_projection.cpp delete mode 100644 examples/identity_direct_usage.cpp create mode 100644 include/beman/dump/dump.hpp delete mode 100644 include/beman/example/identity.hpp create mode 100644 src/beman/dump/CMakeLists.txt rename src/beman/{example/identity.cpp => dump/dump.cpp} (61%) create mode 100644 src/beman/dump/dump.t.cpp delete mode 100644 src/beman/example/CMakeLists.txt delete mode 100644 src/beman/example/identity.t.cpp diff --git a/.ci/docker/rockylinux.Dockerfile b/.ci/docker/rockylinux.Dockerfile index 297e7f0..17823a3 100644 --- a/.ci/docker/rockylinux.Dockerfile +++ b/.ci/docker/rockylinux.Dockerfile @@ -30,6 +30,6 @@ ARG cmake_args= ENV CC="$cc" CXX="$cxx" CMAKE_GENERATOR="Ninja" CMAKE_EXPORT_COMPILE_COMMANDS=on RUN cmake -B build -S . "$cmake_args" RUN cmake --build build --verbose -RUN cmake --install build --prefix /opt/beman.example -RUN find /opt/beman.example -type f +RUN cmake --install build --prefix /opt/beman.dump +RUN find /opt/beman.dump -type f diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dd041dd..99efa63 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # Codeowners for reviews on PRs -* @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey +* @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey @foonathan diff --git a/CMakeLists.txt b/CMakeLists.txt index f4df2e9..957258d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,8 @@ cmake_minimum_required(VERSION 3.23) project( - beman.example # CMake Project Name, which is also the name of the top-level - # targets (e.g., library, executable, etc.). - DESCRIPTION "A Beman Library Example" + beman.dump + DESCRIPTION "std::dump that prints its arguments space-separated with a new-line" LANGUAGES CXX) include(CTest) @@ -24,6 +23,6 @@ if(BUILD_TESTING) FetchContent_MakeAvailable(googletest) endif() -add_subdirectory(src/beman/example) +add_subdirectory(src/beman/dump) add_subdirectory(examples) diff --git a/README.md b/README.md index f19b029..d4fb20f 100644 --- a/README.md +++ b/README.md @@ -2,78 +2,16 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception --> -# beman.example: A Beman Library Example +# beman.dump: Implementation of proposed `std::dump` -![Continuous Integration Tests](https://github.com/beman-project/Example/actions/workflows/ci_tests.yml/badge.svg) +![Continuous Integration Tests](https://github.com/beman-project/dump/actions/workflows/ci_tests.yml/badge.svg) -`beman.example` is a minimal C++ library conforming to [The Beman Standard](https://github.com/beman-project/beman/blob/main/docs/beman-standard.md). This can be used as a template for those intending to write Beman libraries. It may also find use as a minimal and modern C++ project structure. +`std::dump` prints its arguments space-separated with a new-line. +A call to `std::dump(arg1, arg2, …, argn)` is equivalent to `std::println(“{} {} … {}”, arg1, arg2, …, argn)` -Implements: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3). +`std::dump` is proposed by [P2879](https://wg21.link/P2879). This project currently implements R0. - -## Usage - -`std::identity` is a function object type whose `operator()` returns its argument unchanged. `std::identity` serves as the default projection in constrained algorithms. Its direct usage is usually not needed. - -### Usage: default projection in constrained algorithms - - The following code snippet illustrates how we can achieve a default projection using `beman::example::identity`: - - -```cpp -#include - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print(const std::string_view rem, R &&range, Projection projection = beman::example::identity>) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - print("\tpairs with beman: ", pairs); - - return 0; -} - -``` - -Full runable examples can be found in `examples/` (e.g., [./examples/identity_as_default_projection.cpp.cpp](./examples/identity_as_default_projection.cpp.cpp)). - -## Building beman.example +## Building beman.dump ### Dependencies @@ -127,164 +65,64 @@ apt-get install \ -### How to build beman.example +### How to build beman.dump -This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static `libbeman.example.a` library, ready to package with its headers: +This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static `libbeman.dump.a` library, ready to package with its headers: ```shell -cmake -B build -S . -DCMAKE_CXX_STANDARD=20 +cmake -B build -S . cmake --build build ctest --test-dir build -cmake --install build --prefix /opt/beman.example +cmake --install build --prefix /opt/beman.dump ``` +## Integrate beman.dump into your project
- Build example (verbose logs) - -```shell -# Configure example. -$ cmake -B build -S . -DCMAKE_CXX_STANDARD=20 --- The CXX compiler identification is GNU 13.2.0 --- Detecting CXX compiler ABI info --- Detecting CXX compiler ABI info - done --- Check for working CXX compiler: /usr/bin/c++ - skipped --- Detecting CXX compile features --- Detecting CXX compile features - done --- Configuring done (0.1s) --- Generating done (0.0s) --- Build files have been written to: /path/to/repo/build - -# Build example. -$ cmake --build build -[ 10%] Building CXX object src/beman/example/CMakeFiles/beman.example.dir/identity.cpp.o -[ 20%] Linking CXX static library libbeman.example.a -[ 20%] Built target beman.example -[ 30%] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o -[ 40%] Linking CXX static library ../../../lib/libgtest.a -[ 40%] Built target gtest -[ 50%] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -[ 60%] Linking CXX static library ../../../lib/libgtest_main.a -[ 60%] Built target gtest_main -[ 70%] Building CXX object src/beman/example/tests/CMakeFiles/beman.example.Test.dir/identity.t.cpp.o -[ 80%] Linking CXX executable beman.example.Test -[ 80%] Built target beman.example.Test -[ 90%] Building CXX object examples/CMakeFiles/identity_usage.dir/identity_usage.cpp.o -[100%] Linking CXX executable identity_usage -[100%] Built target identity_usage - -# Run tests example. -$ ctest --test-dir build -Internal ctest changing into directory: /path/to/your/repo/build -Test project /path/to/your/repo/build - Start 1: IdentityTest.call_identity_with_int -1/4 Test #1: IdentityTest.call_identity_with_int ........... Passed 0.00 sec - Start 2: IdentityTest.call_identity_with_custom_type -2/4 Test #2: IdentityTest.call_identity_with_custom_type ... Passed 0.00 sec - Start 3: IdentityTest.compare_std_vs_beman -3/4 Test #3: IdentityTest.compare_std_vs_beman ............. Passed 0.00 sec - Start 4: IdentityTest.check_is_transparent -4/4 Test #4: IdentityTest.check_is_transparent ............. Passed 0.00 sec - -100% tests passed, 0 tests failed out of 4 - -Total Test time (real) = 0.01 sec - - -# Run examples. -$ build/examples/beman.example.examples.identity_direct_usage -2024 - -``` - -
- -
- Install example (verbose logs) - -```shell -# Install build artifacts from `build` directory into `opt/beman.example` path. -$ cmake --install build --prefix /opt/beman.example --- Install configuration: "" --- Up-to-date: /opt/beman.example/lib/libbeman.example.a --- Up-to-date: /opt/beman.example/include --- Up-to-date: /opt/beman.example/include/beman --- Up-to-date: /opt/beman.example/include/beman/example --- Up-to-date: /opt/beman.example/include/beman/example/identity.hpp - -# Check tree. -$ tree /opt/beman.example -/opt/beman.example -├── include -│   └── beman -│   └── example -│   └── identity.hpp -└── lib - └── libbeman.example.a - -5 directories, 2 files -``` - -
- -
- Disable tests build - -To build this project with tests disabled (and their dependencies), simply use `BUILD_TESTING=OFF` as documented in upstream [CMake documentation](https://cmake.org/cmake/help/latest/module/CTest.html): - -```shell -cmake -B build -S . -DBUILD_TESTING=OFF -``` - -
- -## Integrate beman.example into your project - -
- Use beman.example directly from C++ + Use beman.dump directly from C++ -If you want to use `beman.example` from your project, you can include `beman/example/*.hpp` files from your C++ source files +If you want to use `beman.dump` from your project, you can include `beman/dump/*.hpp` files from your C++ source files ```cpp -#include +#include ``` -and directly link with `libbeman.example.a` +and directly link with `libbeman.dump.a` ```shell -# Assume /opt/beman.example staging directory. -$ c++ -o identity_usage examples/identity_usage.cpp \ - -I /opt/beman.example/include/ \ - -L/opt/beman.example/lib/ -lbeman.example +# Assume /opt/beman.dump staging directory. +$ c++ -o basic examples/basic.cpp \ + -I /opt/beman.dump/include/ \ + -L/opt/beman.dump/lib/ -lbeman.dump ```
- Use beman.example directly from CMake + Use beman.dump directly from CMake -For CMake based projects, you will need to use the `beman.example` CMake module to define the `beman::example` CMake target: +For CMake based projects, you will need to use the `beman.dump` CMake module to define the `beman::dump` CMake target: ```cmake -find_package(beman.example REQUIRED) +find_package(beman.dump REQUIRED) ``` -You will also need to add `beman::example` to the link libraries of any libraries or executables that include `beman/example/*.hpp` in their source or header file. +You will also need to add `beman::dump` to the link libraries of any libraries or executables that include `beman/dump/*.hpp` in their source or header file. ```cmake -target_link_libraries(yourlib PUBLIC beman::example) +target_link_libraries(yourlib PUBLIC beman::dump) ```
- Use beman.example from other build systems + Use beman.dump from other build systems -Build systems that support `pkg-config` by providing a `beman.example.pc` file. Build systems that support interoperation via `pkg-config` should be able to detect `beman.example` for you automatically. +Build systems that support `pkg-config` by providing a `beman.dump.pc` file. Build systems that support interoperation via `pkg-config` should be able to detect `beman.dump` for you automatically.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a4bbcf3..93edf87 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(ALL_EXAMPLES - #identity_as_default_projection -identity_direct_usage) +add_executable(beman.dump.examples.basic) +target_sources(beman.dump.examples.basic PRIVATE basic.cpp) +target_link_libraries(beman.dump.examples.basic beman::dump) -foreach(example ${ALL_EXAMPLES}) - add_executable(beman.example.examples.${example}) - target_sources(beman.example.examples.${example} PRIVATE ${example}.cpp) - target_link_libraries(beman.example.examples.${example} beman::example) -endforeach() diff --git a/examples/basic.cpp b/examples/basic.cpp new file mode 100644 index 0000000..792f9b4 --- /dev/null +++ b/examples/basic.cpp @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include + +int main() +{ + beman::dump::dump(42, "Hello World!", 3.14, nullptr); +} + diff --git a/examples/identity_as_default_projection.cpp b/examples/identity_as_default_projection.cpp deleted file mode 100644 index aa1fef8..0000000 --- a/examples/identity_as_default_projection.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// This example demonstrates the usage of beman::example::identity as a default projection in a range-printer. -// Requires: range support (C++20) and std::identity support (C++20). -// TODO Darius: Do we need to selectively compile this example? -// Or should we assume that this project is compiled with C++20 support only? - -#include // beman::example::identity - -#include -#include // std::identity -#include -#include -#include - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print_helper(const std::string_view rem, R &&range, Projection projection) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -// Print wrapper with beman::example::identity. -template // <- Notice the default projection. -void print_beman(const std::string_view rem, R &&range, Projection projection = {}) -{ - print_helper(rem, range, projection); -} - -// Print wrapper with std::identity. -template // <- Notice the default projection. -void print_std(const std::string_view rem, R &&range, Projection projection = {}) -{ - print_helper(rem, range, projection); -} - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - std::cout << "Default projection:\n"; - print_beman("\tpairs with beman: ", pairs); - print_std("\tpairs with std: ", pairs); - - // Print the pairs using a custom projection. - std::cout << "Custom projection:\n"; - print_beman("\tpairs with beman: ", pairs, - [](const auto &p) - { return std::to_string(p.n) + ':' + p.s; }); - print_std("\tpairs with std: ", pairs, - [](const auto &p) - { return std::to_string(p.n) + ':' + p.s; }); - - return 0; -} diff --git a/examples/identity_direct_usage.cpp b/examples/identity_direct_usage.cpp deleted file mode 100644 index 90e8444..0000000 --- a/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -int main() { - std::cout << beman::example::identity()(2024) << '\n'; - return 0; -} diff --git a/include/beman/dump/dump.hpp b/include/beman/dump/dump.hpp new file mode 100644 index 0000000..031f49e --- /dev/null +++ b/include/beman/dump/dump.hpp @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_DUMP_DUMP_HPP_INCLUDED +#define BEMAN_DUMP_DUMP_HPP_INCLUDED + +#include +#include +#include + +namespace beman::dump { + namespace detail { + template + constexpr auto format_string = []{ + std::array result{}; + + auto ptr = &result[0]; + for (auto i = 0uz; i != N; ++i) + { + if (i > 0) + *ptr++ = ' '; + *ptr++ = '{'; + *ptr++ = '}'; + } + + return result; + }(); + + template <> + inline constexpr std::array format_string<0>; + } + + template + void dump(Args&&... args) + { + std::println(std::string_view(detail::format_string), std::forward(args)...); + } +} + +#endif // BEMAN_DUMP_DUMP_HPP_INCLUDED + diff --git a/include/beman/example/identity.hpp b/include/beman/example/identity.hpp deleted file mode 100644 index 955fa2d..0000000 --- a/include/beman/example/identity.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_EXAMPLE_IDENTITY_HPP -#define BEMAN_EXAMPLE_IDENTITY_HPP - -// C++ Standard Library: std::identity equivalent. -// See https://eel.is/c++draft/func.identity: -// -// 22.10.12 Class identity [func.identity] -// -// struct identity { -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// using is_transparent = unspecified; -// }; -// -// template -// constexpr T&& operator()(T&& t) const noexcept; -// -// Effects: Equivalent to: return std::forward(t); - -#include // std::forward - -namespace beman::example { - -struct __is_transparent; // not defined - -// A function object that returns its argument unchanged. -struct identity -{ - // Returns `t`. - template -#if defined(__cpp_constexpr) - constexpr -#endif - T && - operator()(T &&t) const noexcept - { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; - -} // namespace beman::example - -#endif // BEMAN_EXAMPLE_IDENTITY_HPP diff --git a/src/beman/dump/CMakeLists.txt b/src/beman/dump/CMakeLists.txt new file mode 100644 index 0000000..86bdc70 --- /dev/null +++ b/src/beman/dump/CMakeLists.txt @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +add_library(beman.dump STATIC) +add_library(beman::dump ALIAS beman.dump) + +target_sources(beman.dump PRIVATE dump.cpp) + +target_include_directories( + beman.dump + PUBLIC $) +target_compile_features( + beman.dump + PUBLIC cxx_std_23) + +install( + TARGETS beman.dump + EXPORT beman.dump + DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp") + +if(BUILD_TESTING) + include(GoogleTest) + + add_executable(beman.dump.tests) + target_sources(beman.dump.tests PRIVATE dump.t.cpp) + target_link_libraries(beman.dump.tests + PRIVATE beman::dump GTest::gtest GTest::gtest_main) + + gtest_add_tests(beman.dump.tests "" AUTO) +endif() diff --git a/src/beman/example/identity.cpp b/src/beman/dump/dump.cpp similarity index 61% rename from src/beman/example/identity.cpp rename to src/beman/dump/dump.cpp index 00e3758..d1aa243 100644 --- a/src/beman/example/identity.cpp +++ b/src/beman/dump/dump.cpp @@ -1,3 +1,4 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include + diff --git a/src/beman/dump/dump.t.cpp b/src/beman/dump/dump.t.cpp new file mode 100644 index 0000000..c6ffeed --- /dev/null +++ b/src/beman/dump/dump.t.cpp @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include + +#include + +TEST(DumpTest, format_string) +{ + using beman::dump::detail::format_string; + + EXPECT_EQ(std::string_view(format_string<0>), ""); + EXPECT_EQ(std::string_view(format_string<1>), "{}"); + EXPECT_EQ(std::string_view(format_string<2>), "{} {}"); + EXPECT_EQ(std::string_view(format_string<3>), "{} {} {}"); +} + + diff --git a/src/beman/example/CMakeLists.txt b/src/beman/example/CMakeLists.txt deleted file mode 100644 index 41e7961..0000000 --- a/src/beman/example/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -add_library(beman.example STATIC) -add_library(beman::example ALIAS beman.example) - -target_sources(beman.example PRIVATE identity.cpp) - -target_include_directories( - beman.example - PUBLIC $) - -install( - TARGETS beman.example - EXPORT beman.example - DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -install( - DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp") - -if(BUILD_TESTING) - include(GoogleTest) - - add_executable(beman.example.tests) - target_sources(beman.example.tests PRIVATE identity.t.cpp) - target_link_libraries(beman.example.tests - PRIVATE beman::example GTest::gtest GTest::gtest_main) - - gtest_add_tests(beman.example.tests "" AUTO) -endif() diff --git a/src/beman/example/identity.t.cpp b/src/beman/example/identity.t.cpp deleted file mode 100644 index 0c39d9c..0000000 --- a/src/beman/example/identity.t.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include - -#include - -#include -#include - -TEST(IdentityTest, call_identity_with_int) -{ - for (int i = -100; i < 100; ++i) - { - EXPECT_EQ(i, beman::example::identity()(i)); - } -} - -TEST(IdentityTest, call_identity_with_custom_type) -{ - struct S - { - int i; - }; - - for (int i = -100; i < 100; ++i) - { - const S s{i}; - const S s_id = beman::example::identity()(s); - EXPECT_EQ(s.i, s_id.i); - } -} - -TEST(IdentityTest, compare_std_vs_beman) -{ -// Requires: std::identity support. -#if defined(__cpp_lib_identity) - std::identity std_id; - beman::example::identity beman_id; - for (int i = -100; i < 100; ++i) - { - EXPECT_EQ(std_id(i), beman_id(i)); - } -#endif -} - -TEST(IdentityTest, check_is_transparent) -{ -// Requires: transparent operators support. -#if defined(__cpp_lib_transparent_operators) - - beman::example::identity id; - - const auto container = {1, 2, 3, 4, 5}; - auto it = std::find(std::begin(container), std::end(container), 3); - EXPECT_EQ(3, *it); - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -#endif -} From c96561ac9e9df02c4c915e5a7a317e8381c97b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 19 Sep 2024 22:27:42 -0600 Subject: [PATCH 02/16] Remove broken/unnecessary CI systems --- .github/workflows/ci_tests.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 9ac70a6..0f3c8cc 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -25,23 +25,10 @@ jobs: strategy: matrix: cfg: - - { id: ubuntu-gcc-werror, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_FLAGS='-Werror=all -Werror=extra'"} - - { id: ubuntu-gcc-aubsan, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_FLAGS=-fsanitize=address -fsanitize=undefined"} - - { id: ubuntu-gcc-tsan, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_FLAGS=-fsanitize=thread"} - - { id: ubuntu-gcc-static, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: ""} - - { id: ubuntu-gcc-dynamic, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DBUILD_SHARED_LIBS=on"} - - { id: ubuntu-clang-static, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: ""} - - { id: ubuntu-clang-dynamic, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DBUILD_SHARED_LIBS=on"} - - { id: ubuntu-gcc-static-cxx20, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - { id: ubuntu-gcc-static-cxx23, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - { id: ubuntu-gcc-static-cxx26, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - - { id: ubuntu-clang-static-cxx20, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - { id: ubuntu-clang-static-cxx23, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - { id: ubuntu-clang-static-cxx26, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - # Disabling Rocky until it catches up on CMake versions or a way to sideload newer version of CMake - # is identified. - # - { id: rockylinux-gcc-static, platform: rockylinux, cc: gcc, cpp: g++, cmake_args: ""} - # - { id: rockylinux-clang-static, platform: rockylinux, cc: clang, cpp: clang++, cmake_args: ""} steps: - uses: actions/checkout@v2 From 88c9f9759d445c04e8c0f5530a220b0d8a318348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 19 Sep 2024 22:35:04 -0600 Subject: [PATCH 03/16] Rewrite CI --- .ci/docker/rockylinux.Dockerfile | 35 ----------------- .ci/docker/ubuntu.Dockerfile | 34 ----------------- .github/workflows/ci_tests.yml | 64 +++++++++++--------------------- 3 files changed, 21 insertions(+), 112 deletions(-) delete mode 100644 .ci/docker/rockylinux.Dockerfile delete mode 100644 .ci/docker/ubuntu.Dockerfile diff --git a/.ci/docker/rockylinux.Dockerfile b/.ci/docker/rockylinux.Dockerfile deleted file mode 100644 index 17823a3..0000000 --- a/.ci/docker/rockylinux.Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -FROM rockylinux:9 - -# Enable EPEL. -RUN dnf update -y -RUN dnf install -y 'dnf-command(config-manager)' -RUN dnf config-manager --set-enabled crb -y -RUN dnf install epel-release -y - -# Install dependencies. -RUN dnf install -y \ - clang \ - g++ \ - ninja-build \ - cmake \ - git -RUN dnf clean all - -# Copy code. -WORKDIR /workarea -COPY ./ ./ - -# Set build arguments. -ARG cc=gcc -ARG cxx=g++ -ARG cmake_args= - -# Build. -ENV CC="$cc" CXX="$cxx" CMAKE_GENERATOR="Ninja" CMAKE_EXPORT_COMPILE_COMMANDS=on -RUN cmake -B build -S . "$cmake_args" -RUN cmake --build build --verbose -RUN cmake --install build --prefix /opt/beman.dump -RUN find /opt/beman.dump -type f - diff --git a/.ci/docker/ubuntu.Dockerfile b/.ci/docker/ubuntu.Dockerfile deleted file mode 100644 index cfb3c81..0000000 --- a/.ci/docker/ubuntu.Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# Using a non-LTS Ubuntu, just until CMake 3.23 is available on Ubuntu 24.04. -FROM ubuntu:23.10 - -# Install dependencies, -RUN apt-get update -RUN apt-get install -y \ - clang \ - clang-tidy \ - g++ \ - ninja-build \ - cmake \ - git -RUN apt-get clean - -WORKDIR /workarea -COPY ./ ./ - -# Set build arguments. -ARG cc=gcc -ARG cxx=g++ -ARG cmake_args= - -# Workaround Ubuntu broken ASan -RUN sysctl vm.mmap_rnd_bits=28 - -# Build. -ENV CC="$cc" CXX="$cxx" CMAKE_GENERATOR="Ninja" CMAKE_EXPORT_COMPILE_COMMANDS=on -RUN ls -lR src -RUN cmake -B build -S . "$cmake_args" -RUN cmake --build build --verbose -RUN cmake --install build --prefix /opt/beman.example -RUN find /opt/beman.example -type f diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 0f3c8cc..a32156f 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -21,50 +21,28 @@ on: jobs: test: - runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - cfg: - - { id: ubuntu-gcc-static-cxx23, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - - { id: ubuntu-gcc-static-cxx26, platform: ubuntu, cc: gcc, cpp: g++, cmake_args: "-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - - { id: ubuntu-clang-static-cxx23, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_STANDARD_REQUIRED=on"} - - { id: ubuntu-clang-static-cxx26, platform: ubuntu, cc: clang, cpp: clang++, cmake_args: "-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=on"} + image: + - "gcc:14" + build_type: [Debug, Release] + + runs-on: ubuntu-latest + container: + image: ghcr.io/foonathan/${{matrix.image}} steps: - - uses: actions/checkout@v2 - # GitHub runners have updated the Ubuntu Linux Kernel to use strong ASLR, - # but LLVM is not configured for this change, and thus the address - # sanitizer breaks. - # - # The next image is supposed to fix this, so if the Ubuntu image has been - # updated, this work around is no longer required. - - name: get runner image version - id: runner-image-version - run: | - echo "image-version=$(echo $ImageVersion)" >> "$GITHUB_OUTPUT" - working-directory: . - - name: modify number of bits to use for ASLR entropy - if: ${{ steps.runner-image-version.outputs.ImageVersion }} == '20240310.1.0' - run: | - sudo sysctl -a | grep vm.mmap.rnd - sudo sysctl -w vm.mmap_rnd_bits=28 - working-directory: . - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - push: false - load: true - tags: ${{ matrix.cfg.id }} - file: .ci/docker/${{ matrix.cfg.platform }}.Dockerfile - build-args: | - cc=${{ matrix.cfg.cc }} - cxx=${{ matrix.cfg.cpp }} - cmake_args=${{ matrix.cfg.cmake_args }} - cache-from: type=gha - cache-to: type=gha,mode=max - - name: Run tests - run: | - docker run ${{ matrix.cfg.id }} ctest --test-dir build + - uses: actions/checkout@v4 + - name: Create Build Environment + run: cmake -E make_directory build + + - name: Configure + working-directory: build/ + run: cmake -GNinja $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_CXX_FLAGS="-Werror -Wall -Wextra" + - name: Build + working-directory: build/ + run: cmake --build . + - name: Test + working-directory: build/ + run: ctest --output-on-failure From 512e953607a41ae8fef195805228135d80621815 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:38:17 -0500 Subject: [PATCH 04/16] Update CMakeLists.txt Co-authored-by: David Sankel --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 957258d..e2a6a25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.23) project( beman.dump - DESCRIPTION "std::dump that prints its arguments space-separated with a new-line" + DESCRIPTION "A dump function that prints its arguments space-separated with a new-line" LANGUAGES CXX) include(CTest) From d6d431d7b1a3f93331277a4663adcdd0c03a03a9 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:38:32 -0500 Subject: [PATCH 05/16] Update wording Co-authored-by: David Sankel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4fb20f..ede7291 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception --> -# beman.dump: Implementation of proposed `std::dump` +# beman.dump: A tool for dumping an object's value to standard output ![Continuous Integration Tests](https://github.com/beman-project/dump/actions/workflows/ci_tests.yml/badge.svg) From 2fe0e5c4e093c171d4351f35bf05b7b616218a16 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:38:42 -0500 Subject: [PATCH 06/16] Update wording Co-authored-by: David Sankel --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ede7291..5279029 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ![Continuous Integration Tests](https://github.com/beman-project/dump/actions/workflows/ci_tests.yml/badge.svg) -`std::dump` prints its arguments space-separated with a new-line. +`beman::dump::dump()` prints its arguments space-separated with a new-line. This +is useful as a debugging utility. A call to `std::dump(arg1, arg2, …, argn)` is equivalent to `std::println(“{} {} … {}”, arg1, arg2, …, argn)` `std::dump` is proposed by [P2879](https://wg21.link/P2879). This project currently implements R0. From 4e034f6937d011eef6327aab2d5230fc2097b060 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:38:55 -0500 Subject: [PATCH 07/16] Update wording Co-authored-by: David Sankel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5279029..0f4d4fb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception `beman::dump::dump()` prints its arguments space-separated with a new-line. This is useful as a debugging utility. -A call to `std::dump(arg1, arg2, …, argn)` is equivalent to `std::println(“{} {} … {}”, arg1, arg2, …, argn)` +A call to `beman::dump::dump(arg1, arg2, …, argn)` is equivalent to `std::println(“{} {} … {}”, arg1, arg2, …, argn)` `std::dump` is proposed by [P2879](https://wg21.link/P2879). This project currently implements R0. From 7dec0841fe2ca4aba24d66bd39dc91f6965879fb Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:39:17 -0500 Subject: [PATCH 08/16] Update wording Co-authored-by: David Sankel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f4d4fb..62ebc16 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception is useful as a debugging utility. A call to `beman::dump::dump(arg1, arg2, …, argn)` is equivalent to `std::println(“{} {} … {}”, arg1, arg2, …, argn)` -`std::dump` is proposed by [P2879](https://wg21.link/P2879). This project currently implements R0. +- Implements: [Proposal of `std::dump` (P2879R0)](https://wg21.link/P2879R0) ## Building beman.dump From c491d841709f6d1832186b6dc523f608de3b03e8 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:39:31 -0500 Subject: [PATCH 09/16] Update README.md Co-authored-by: David Sankel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62ebc16..f4633ae 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ cmake --install build --prefix /opt/beman.dump If you want to use `beman.dump` from your project, you can include `beman/dump/*.hpp` files from your C++ source files ```cpp -#include +#include ``` and directly link with `libbeman.dump.a` From 9f3a6abcf17bf2abe0e6f2602889b2b4c4b2923c Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:40:59 -0500 Subject: [PATCH 10/16] add todo --- include/beman/dump/dump.hpp | 51 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/include/beman/dump/dump.hpp b/include/beman/dump/dump.hpp index 031f49e..7c823c9 100644 --- a/include/beman/dump/dump.hpp +++ b/include/beman/dump/dump.hpp @@ -8,33 +8,30 @@ #include namespace beman::dump { - namespace detail { - template - constexpr auto format_string = []{ - std::array result{}; - - auto ptr = &result[0]; - for (auto i = 0uz; i != N; ++i) - { - if (i > 0) - *ptr++ = ' '; - *ptr++ = '{'; - *ptr++ = '}'; - } - - return result; - }(); - - template <> - inline constexpr std::array format_string<0>; - } - - template - void dump(Args&&... args) - { - std::println(std::string_view(detail::format_string), std::forward(args)...); - } +namespace detail { +template +constexpr auto format_string = [] { + std::array result{}; + + auto ptr = &result[0]; + for (auto i = 0uz; i != N; ++i) { + if (i > 0) + *ptr++ = ' '; + *ptr++ = '{'; + *ptr++ = '}'; + } + + return result; +}(); + +template <> inline constexpr std::array format_string<0>; +} // namespace detail + +// TODO: Need documentation +template void dump(Args &&...args) { + std::println(std::string_view(detail::format_string), + std::forward(args)...); } +} // namespace beman::dump #endif // BEMAN_DUMP_DUMP_HPP_INCLUDED - From dd5eba91819db3a0e1216a92a5f06ee095c68a51 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:42:20 -0500 Subject: [PATCH 11/16] Update src/beman/dump/dump.t.cpp Co-authored-by: David Sankel --- src/beman/dump/dump.t.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/beman/dump/dump.t.cpp b/src/beman/dump/dump.t.cpp index c6ffeed..2fb79c1 100644 --- a/src/beman/dump/dump.t.cpp +++ b/src/beman/dump/dump.t.cpp @@ -13,5 +13,3 @@ TEST(DumpTest, format_string) EXPECT_EQ(std::string_view(format_string<2>), "{} {}"); EXPECT_EQ(std::string_view(format_string<3>), "{} {} {}"); } - - From 82657ac2c2a99b46487746e8545e49b00112af90 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:42:59 -0500 Subject: [PATCH 12/16] add todo --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f4633ae..31dcf1e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ A call to `beman::dump::dump(arg1, arg2, …, argn)` is equivalent to `std::prin ## Building beman.dump +## Usage + +TODO + ### Dependencies From 55792ad3f1da8863005510500e1fcee92ba6fc16 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:44:04 -0500 Subject: [PATCH 13/16] add return in main --- examples/basic.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/basic.cpp b/examples/basic.cpp index 792f9b4..be055af 100644 --- a/examples/basic.cpp +++ b/examples/basic.cpp @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include -int main() -{ - beman::dump::dump(42, "Hello World!", 3.14, nullptr); +int main() { + beman::dump::dump(42, "Hello World!", 3.14, nullptr); + return EXIT_SUCCESS; } - From 6e9f7b4429b9482430cd65bc2495c3c4ed2ceb4e Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:45:31 -0500 Subject: [PATCH 14/16] Update src/beman/dump/dump.cpp Co-authored-by: David Sankel --- src/beman/dump/dump.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/beman/dump/dump.cpp b/src/beman/dump/dump.cpp index d1aa243..ce96841 100644 --- a/src/beman/dump/dump.cpp +++ b/src/beman/dump/dump.cpp @@ -1,4 +1,3 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include - From b74b84cea1c857de1ea304edbb82e62d689a65e1 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:47:35 -0500 Subject: [PATCH 15/16] add todo --- include/beman/dump/dump.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/beman/dump/dump.hpp b/include/beman/dump/dump.hpp index 7c823c9..6233182 100644 --- a/include/beman/dump/dump.hpp +++ b/include/beman/dump/dump.hpp @@ -9,6 +9,7 @@ namespace beman::dump { namespace detail { +// TODO: Need documentation template constexpr auto format_string = [] { std::array result{}; From e091bc92dada6e7ed86c305592db389f0b9685ca Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:48:25 -0500 Subject: [PATCH 16/16] use std::invoke --- include/beman/dump/dump.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/beman/dump/dump.hpp b/include/beman/dump/dump.hpp index 6233182..a2b8975 100644 --- a/include/beman/dump/dump.hpp +++ b/include/beman/dump/dump.hpp @@ -4,6 +4,7 @@ #define BEMAN_DUMP_DUMP_HPP_INCLUDED #include +#include #include #include @@ -11,7 +12,7 @@ namespace beman::dump { namespace detail { // TODO: Need documentation template -constexpr auto format_string = [] { +constexpr auto format_string = std::invoke([] { std::array result{}; auto ptr = &result[0]; @@ -23,7 +24,7 @@ constexpr auto format_string = [] { } return result; -}(); +}); template <> inline constexpr std::array format_string<0>; } // namespace detail