diff --git a/.ci/docker/rockylinux.Dockerfile b/.ci/docker/rockylinux.Dockerfile deleted file mode 100644 index 297e7f0..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.example -RUN find /opt/beman.example -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/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/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 9ac70a6..a32156f 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -21,63 +21,28 @@ on: jobs: test: - runs-on: ubuntu-latest strategy: + fail-fast: false 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: ""} + 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index f4df2e9..e2a6a25 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 "A dump function 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 9619cbb..45c8d1f 100644 --- a/README.md +++ b/README.md @@ -2,78 +2,21 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception --> -# beman.example: A Beman Library Example +# beman.dump: A tool for dumping an object's value to standard output -![Continuous Integration Tests](https://github.com/bemanproject/Example/actions/workflows/ci_tests.yml/badge.svg) +![Continuous Integration Tests](https://github.com/bemanproject/dump/actions/workflows/ci_tests.yml/badge.svg) -`beman.example` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/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. +`beman::dump::dump()` prints its arguments space-separated with a new-line. This +is useful as a debugging utility. +A call to `beman::dump::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). +- Implements: [Proposal of `std::dump` (P2879R0)](https://wg21.link/P2879R0) +## Building beman.dump ## 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 +TODO ### Dependencies @@ -127,164 +70,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..be055af --- /dev/null +++ b/examples/basic.cpp @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +int main() { + beman::dump::dump(42, "Hello World!", 3.14, nullptr); + return EXIT_SUCCESS; +} 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..a2b8975 --- /dev/null +++ b/include/beman/dump/dump.hpp @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_DUMP_DUMP_HPP_INCLUDED +#define BEMAN_DUMP_DUMP_HPP_INCLUDED + +#include +#include +#include +#include + +namespace beman::dump { +namespace detail { +// TODO: Need documentation +template +constexpr auto format_string = std::invoke([] { + 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 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..ce96841 100644 --- a/src/beman/example/identity.cpp +++ b/src/beman/dump/dump.cpp @@ -1,3 +1,3 @@ // 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..2fb79c1 --- /dev/null +++ b/src/beman/dump/dump.t.cpp @@ -0,0 +1,15 @@ +// 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 -}