diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..1c8a246c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.bib -linguist-detectable +*.tex -linguist-detectable +papers/* linguist-documentation diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7947a633..3fd63e14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,67 +1,28 @@ name: Test - on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] - + branches: [main] jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} - strategy: fail-fast: false - matrix: config: - - { - name: "Ubuntu Clang 17", - os: ubuntu-24.04, - toolchain: "clang-17-toolchain.cmake", - clang_version: 17, - installed_clang_version: 14, - cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" " - } - - - { - name: "Ubuntu Clang 18", - os: ubuntu-24.04, - toolchain: "clang-18-toolchain.cmake", - clang_version: 18, - installed_clang_version: 14, - cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" " - } - - - { - name: "Ubuntu GCC 13", - os: ubuntu-24.04, - toolchain: "gcc-13-toolchain.cmake", - clang_version: 17, - installed_clang_version: 14, - cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" " - } - - - { - name: "Ubuntu GCC 14", - os: ubuntu-24.04, - toolchain: "gcc-14-toolchain.cmake", - clang_version: 17, - installed_clang_version: 14, - cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" " - } - + - {name: "Ubuntu Clang 17", os: ubuntu-24.04, toolchain: "clang-17-toolchain.cmake", clang_version: 17, installed_clang_version: 14, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu Clang 18", os: ubuntu-24.04, toolchain: "clang-18-toolchain.cmake", clang_version: 18, installed_clang_version: 14, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu GCC 13", os: ubuntu-24.04, toolchain: "gcc-13-toolchain.cmake", clang_version: 17, installed_clang_version: 14, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu GCC 14", os: ubuntu-24.04, toolchain: "gcc-14-toolchain.cmake", clang_version: 17, installed_clang_version: 14, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} steps: - uses: actions/checkout@v3 with: submodules: 'true' - - uses: seanmiddleditch/gha-setup-ninja@master - - name: Activate verbose shell run: set -x - - name: Install LLVM+Clang if: startsWith(matrix.config.os, 'ubuntu-') run: | @@ -89,15 +50,11 @@ jobs: chmod +x llvm.sh sudo ./llvm.sh ${{matrix.config.clang_version}} all sudo apt-get install libc++-dev libc++1 libc++abi-dev libc++abi1 - - - name: Install GCC 14 if: matrix.config.name == 'Ubuntu GCC 14' run: | sudo apt update sudo apt-get install g++-14 - - - name: Configure run: | rm -rf .build @@ -106,11 +63,9 @@ jobs: echo ${{ matrix.config.cmake_args }} echo ${{ matrix.config.toolchain }} cmake ${{ matrix.config.cmake_args }} -DCMAKE_TOOLCHAIN_FILE=etc/${{ matrix.config.toolchain }} -B . -S .. - - name: Build run: | cmake --build .build --config Asan --target all -- -k 0 - - name: Test run: | cd .build diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000..498e2eac --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,4 @@ +{ + "MD013": false, + "MD024": false +} diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 00000000..2dbfffc7 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,3 @@ +# shellcheck +# allow for non-alphanumeric filenames +disable=SC2038 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7de1a05b..564e9d76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,14 @@ +# cmake-format: off # /CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on cmake_minimum_required(VERSION 3.10) -project(beman_optional26 VERSION 0.0.0 LANGUAGES CXX) +project( + beman_optional26 + VERSION 0.0.0 + LANGUAGES CXX) enable_testing() @@ -20,25 +25,21 @@ set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake) install( EXPORT ${TARGETS_EXPORT_NAME} NAMESPACE ${CMAKE_PROJECT_NAME} - DESTINATION ${INSTALL_CONFIGDIR} - ) + DESTINATION ${INSTALL_CONFIGDIR}) include(CMakePackageConfigHelpers) write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion -) + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion) configure_package_config_file( - "cmake/Config.cmake.in" - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${INSTALL_CONFIGDIR} -) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake - DESTINATION ${INSTALL_CONFIGDIR} -) + "cmake/Config.cmake.in" + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${INSTALL_CONFIGDIR}) diff --git a/CMakePresets.json b/CMakePresets.json index faac880e..40cb22a2 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -31,12 +31,33 @@ "description": "Build with GCC 14 compilers", "toolchainFile": "${sourceDir}/etc/gcc-14-toolchain.cmake" }, + { + "name": "gcc-13", + "inherits": "common", + "displayName": "GCC 13", + "description": "Build with GCC 13 compilers", + "toolchainFile": "${sourceDir}/etc/gcc-13-toolchain.cmake" + }, + { + "name": "clang-19", + "inherits": "common", + "displayName": "Clang 19", + "description": "Build with Clang 19 compilers", + "toolchainFile": "${sourceDir}/etc/clang-19-toolchain.cmake" + }, { "name": "clang-18", "inherits": "common", "displayName": "Clang 18", "description": "Build with Clang 18 compilers", "toolchainFile": "${sourceDir}/etc/clang-18-toolchain.cmake" + }, + { + "name": "clang-17", + "inherits": "common", + "displayName": "Clang 17", + "description": "Build with Clang 17 compilers", + "toolchainFile": "${sourceDir}/etc/clang-17-toolchain.cmake" } ], "buildPresets": [ @@ -53,9 +74,21 @@ "name": "gcc-14", "configurePreset": "gcc-14" }, + { + "name": "gcc-13", + "configurePreset": "gcc-13" + }, + { + "name": "clang-19", + "configurePreset": "clang-19" + }, { "name": "clang-18", "configurePreset": "clang-18" + }, + { + "name": "clang-17", + "configurePreset": "clang-17" } ], "testPresets": [ @@ -80,10 +113,25 @@ "inherits": "common", "configurePreset": "gcc-14" }, + { + "name": "gcc-13", + "inherits": "common", + "configurePreset": "gcc-13" + }, + { + "name": "clang-19", + "inherits": "common", + "configurePreset": "clang-19" + }, { "name": "clang-18", "inherits": "common", "configurePreset": "clang-18" + }, + { + "name": "clang-17", + "inherits": "common", + "configurePreset": "clang-17" } ], "workflowPresets": [ @@ -121,6 +169,40 @@ } ] }, + { + "name": "gcc-13", + "steps": [ + { + "type": "configure", + "name": "gcc-13" + }, + { + "type": "build", + "name": "gcc-13" + }, + { + "type": "test", + "name": "gcc-13" + } + ] + }, + { + "name": "clang-19", + "steps": [ + { + "type": "configure", + "name": "clang-19" + }, + { + "type": "build", + "name": "clang-19" + }, + { + "type": "test", + "name": "clang-19" + } + ] + }, { "name": "clang-18", "steps": [ @@ -137,6 +219,23 @@ "name": "clang-18" } ] + }, + { + "name": "clang-17", + "steps": [ + { + "type": "configure", + "name": "clang-17" + }, + { + "type": "build", + "name": "clang-17" + }, + { + "type": "test", + "name": "clang-17" + } + ] } ] } diff --git a/Makefile b/Makefile index f675d76b..b27aabc4 100755 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ #! /usr/bin/make -f +# cmake-format: off # /Makefile -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on INSTALL_PREFIX?=.install/ PROJECT?=$(shell basename $(CURDIR)) diff --git a/README.md b/README.md index 2a3f2fad..08c550c1 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,11 @@ SPDX-License-Identifier: 2.0 license with LLVM exceptions --> -This implementation incorporates the C++26 extensions added for `std::optional`. The `Beman.Optional26` library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 into the C++ Working Draft. Additionally, it allows developers to use these new features before they are implemented in major standard library compilers. +This repository implements `std::optional` extensions targeting C++26. The `Beman.Optional26` library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 into the C++ Working Draft. Additionally, it allows developers to use these new features before they are implemented in major standard library compilers. **Implements**: -* [Give *std::optional* Range Support (P3168R1)](https://wg21.link/P3168R1) + +* [Give *std::optional* Range Support (P3168R2)](https://wg21.link/P3168R2) * [`std::optional` (P2988R5)](https://wg21.link/P2988R5) ## License @@ -32,13 +33,13 @@ Full runable examples can be found in `examples/` - please check [./examples/REA ### range_loop -The next code snippet shows optional range support added in [Give *std::optional* Range Support (P3168R1)](https://wg21.link/P3168R1): +The next code snippet shows optional range support added in [Give *std::optional* Range Support (P3168R2)](https://wg21.link/P3168R2): ```cpp #include ... -// Example from P3168R1: basic range loop over C++26 optional. +// Example from P3168R2: basic range loop over C++26 optional. beman::optional26::optional empty_opt{}; for ([[maybe_unused]] const auto& i : empty_opt) { @@ -53,7 +54,7 @@ for (const auto& i : opt) { } ``` -Full code can be found in [./examples/range_loop.cpp](./examples/range_loop.cpp). Build and run instructions in [./examples/README.md](./examples/README.md). Or [try it on compiler explorer](https://godbolt.org/z/b5ThEqqhf) +Full code can be found in [./examples/range_loop.cpp](./examples/range_loop.cpp). Build and run instructions in [./examples/README.md](./examples/README.md). Or [try it on Compiler Explorer](https://godbolt.org/z/b5ThEqqhf). ### optional_ref @@ -96,35 +97,71 @@ Default build: `C++23`. Please check `etc/${compiler}-flags.cmake`. ### Dependencies -This project is mainly tested on `Ubuntu 22.04` and `Ubuntu 24.04`, but it should be as portable as CMake is. This project has zero C or C++ dependencies. +This project is mainly tested on `Ubuntu 22.04` and `Ubuntu 24.04`, but it should be as portable as CMake is. This project has no C or C++ dependencies. -It does require few tools as build-time dependencies: +Build-time dependencies: -- `cmake` -- `ninja`, `make`, or another CMake-supported build system - - CMake defaults to "Unix Makefiles" on POSIX systems +* `cmake` +* `ninja`, `make`, or another CMake-supported build system + * CMake defaults to "Unix Makefiles" on POSIX systems Example of installation on `Ubuntu 24.04`: + ```shell -# install tools +# Install tools: apt-get install -y cmake make ninja-build -# example of toolchains -apt-get install g++-14 gcc-14 clang-18 clang++-18 +# Example of toolchains: +apt-get install \ + g++-14 gcc-14 gcc-13 g++-14 \ + clang-18 clang++-18 clang-17 clang++-17 ``` ### Instructions -Full set of supported toolchains can be found in [.github/workflows/ci.yml](#.github/workflows/ci.yml). +Full set of supported toolchains can be found in [.github/workflows/ci.yml](.github/workflows/ci.yml). #### Basic Build This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static `beman_optional26` library, ready to package: ```shell +# List available preset configurations: +$ cmake --workflow --list-presets +Available workflow presets: + + "system" + "gcc-14" + "gcc-13" + "clang-18" + "clang-17" + +# Run examples: +$ cmake --workflow --preset gcc-14 cmake --workflow --preset gcc-14 -cmake --workflow --preset clang-18 -cmake --workflow --preset systems # uses c++ set tool +Executing workflow step 1 of 3: configure preset "gcc-14" +... +-- Build files have been written to: /path/to/repo/.build/gcc-14 + +Executing workflow step 2 of 3: build preset "gcc-14" + +ninja: no work to do. + +Executing workflow step 3 of 3: test preset "gcc-14" + +Test project /path/to/repo/.build/gcc-14 + Start 1: OptionalTest.TestGTest + 1/... Test #1: OptionalTest.TestGTest ........................... Passed 0.00 sec +... + Start x: RangeSupportTest.RangeConcepts +.../... Test #x: RangeSupportTest.RangeConcepts ................... Passed 0.00 sec + Start x+1: RangeSupportTest.IteratorConcepts +.../... Test #x+1: RangeSupportTest.IteratorConcepts ................ Passed 0.00 sec +... + +100% tests passed, 0 tests failed out of ... + +Total Test time (real) = 0.09 sec ``` This should build and run the tests with GCC 14 with the address and undefined behavior sanitizers enabled. @@ -142,14 +179,15 @@ The makefile will use your system compiler, `c++`, if no toolchain name is provi ## Papers Latest revision(s) of the papers can be built / found at: + * [give-std-optional-range-support](https://github.com/neatudarius/give-std-optional-range-support/) for `Give *std::optional* Range Support (P3168)` - * issue: [#1831](https://github.com/cplusplus/papers/issues/1831) + * issue: [#1831](https://github.com/cplusplus/papers/issues/1831) * LEWG: * Reviewed in Tokyo 2024. * Forwarded by LEWG April electronic poll to LWG. * LWG: * Reviewed and approved in Saint Louis 2024. * [./papers/P2988/README.md](./papers/P2988/README.md) for `std::optional (P2988)`. - * issue: [#1661](https://github.com/cplusplus/papers/issues/1661) - * LEWG: - * Reviewed in Tokyo 2024. + * issue: [#1661](https://github.com/cplusplus/papers/issues/1661) + * LEWG: + * Reviewed in Tokyo 2024. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f1781006..f53cbfdb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,29 +1,22 @@ +# cmake-format: off # examples/CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on set(BEMAN_OPTIONAL26_LIBRARY "beman_optional26") include(GNUInstallDirs) # List of all buildable examples. -set(EXAMPLES - optional_ref - pythagorean_triples - range_loop - sample - std_vs_beman -) +set(EXAMPLES concept_checks optional_ref pythagorean_triples range_loop sample + std_vs_beman) foreach(EXAMPLE ${EXAMPLES}) # Add example executable. add_executable(${EXAMPLE} "") # Add example source file. - target_sources( - ${EXAMPLE} - PRIVATE - ${EXAMPLE}.cpp - ) + target_sources(${EXAMPLE} PRIVATE ${EXAMPLE}.cpp) # Link example with the library. target_link_libraries(${EXAMPLE} "${BEMAN_OPTIONAL26_LIBRARY}") @@ -32,6 +25,5 @@ foreach(EXAMPLE ${EXAMPLES}) install( TARGETS ${EXAMPLE} EXPORT ${TARGETS_EXPORT_NAME} - DESTINATION ${CMAKE_INSTALL_BINDIR} - ) + DESTINATION ${CMAKE_INSTALL_BINDIR}) endforeach() diff --git a/examples/README.md b/examples/README.md index a8b6827a..892a9282 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,26 +6,16 @@ SPDX-License-Identifier: 2.0 license with LLVM exceptions List of usage examples for `Beman.Optional26`. -## License -Source is licensed with the Apache 2.0 license with LLVM exceptions +## Samples -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +Check basic `Beman.Optional26` library usages: -Documentation and associated papers are licensed with the Creative Commons Attribution 4.0 International license. +* local [./sample.cpp](./sample.cpp) or [sample.cpp@Compiler Explorer](https://godbolt.org/z/47vGje65x) +* local [./std_vs_beman.cpp](./std_vs_beman.cpp) or [std_vs_beman.cpp@Compiler Explorer](https://godbolt.org/z/ds5MvfGe6) +* local [./concept_checks.cpp](./concep_checks.cpp) or [concept_checks.cpp@Compiler Explorer](https://godbolt.org/z/7eYb4Wbjc) -// SPDX-License-Identifier: CC-BY-4.0 +### Local Build and Run -The intent is that the source and documentation are available for use by people implementing their own optional types as well as people using the optional presented here as-is. - -The README itself is licesed with CC0 1.0 Universal. Copy the contents and incorporate in your own work as you see fit. - -// SPDX-License-Identifier: CC0-1.0 - -## Sample - -Check [sample](sample.cpp) for basic `Beman.Optional26` library usage. - -Build and run instructions: ```shell # build $ cmake --workflow --preset gcc-14 @@ -39,19 +29,23 @@ opt = 26 $ .build/gcc-14/examples/RelWithDebInfo/std_vs_beman std_vs_beman: .has_value() matches?: yes std_vs_beman: .value() matches?: yes + +# run concept_checks.cpp +$ .build/gcc-14/examples/RelWithDebInfo/concept_checks ``` -## Range Support (P3168R1) +## Range Support (P3168R2) -Range support added in [*Give std::optional Range Support* (P3168R1)](https://wg21.link/P3168R1) examples: -* [./range_loop.cpp](./range_loop.cpp) -* [./pythagorean_triples.cpp](./pythagorean_triples.cpp) +Range support added in [*Give std::optional Range Support* (P3168R2)](https://wg21.link/P3168R2) examples: +* local [./range_loop.cpp](./range_loop.cpp) or [range_loop.cpp@Compiler Explorer](https://godbolt.org/z/f8dWaxsGo) +* local [./pythagorean_triples.cpp](./pythagorean_triples.cpp) or [pythagorean_triples.cpp@Compiler Explorer](https://godbolt.org/z/fGr8jYM6P) -Build and run instructions: +### Local Build and Run ```shell - +# build +$ cmake --workflow --preset gcc-14 # run range_loop.cpp $ .build/gcc-14/examples/RelWithDebInfo/range_loop @@ -78,9 +72,9 @@ First 10 Pythagorean triples: Reference support added in [*std::optional*(P2988R5)](https://wg21.link/P2988R5) examples: -* [./optional_ref.cpp](./optional_ref.cpp) +* local [./optional_ref.cpp](./optional_ref.cpp) or [optional_ref.cpp@Compiler Explorer](https://godbolt.org/z/nbfjsY9Gs) -Build and run instructions: +### Local Build and Run ```shell # build diff --git a/examples/concept_checks.cpp b/examples/concept_checks.cpp new file mode 100644 index 00000000..51eed4b0 --- /dev/null +++ b/examples/concept_checks.cpp @@ -0,0 +1,104 @@ +// examples/concept_checks.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +#include + +namespace test { +// Classes used in the tests. + +// Empty class helper. +struct empty {}; + +// No default constructor class helper. +struct no_default_ctor { + no_default_ctor() = delete; + no_default_ctor(const no_default_ctor&) = default; + no_default_ctor(no_default_ctor&&) = default; + no_default_ctor& operator=(const no_default_ctor&) = default; + no_default_ctor& operator=(no_default_ctor&&) = default; + no_default_ctor(empty) {}; +}; + +// Base class helper. +struct base { + int m_i; + base() : m_i(0) {} + base(int i) : m_i(i) {} +}; + +// Derived class helper. +struct derived : public base { + int m_j; + derived() : base(), m_j(0) {} + derived(int i, int j) : base(i), m_j(j) {} +}; + +} // namespace test + +const auto test_concepts_disabled = [](auto&& opt) { + // The optional type is the opt type without the reference. + using optional = std::remove_reference_t; + + // Check std::ranges concepts not enabled. + static_assert(!std::ranges::range); + static_assert(!std::ranges::view); + static_assert(!std::ranges::input_range); + static_assert(!std::ranges::forward_range); + static_assert(!std::ranges::bidirectional_range); + static_assert(!std::ranges::contiguous_range); + static_assert(!std::ranges::common_range); + static_assert(!std::ranges::viewable_range); + static_assert(!std::ranges::random_access_range); + static_assert(!std::ranges::sized_range); +}; + +const auto test_concepts_enabled = [](auto&& opt) { + // The optional type is the opt type without the reference. + using optional = std::remove_reference_t; + + // Check std::ranges concepts enabled. + static_assert(std::ranges::range); + static_assert(std::ranges::view); + static_assert(std::ranges::input_range); + static_assert(std::ranges::forward_range); + static_assert(std::ranges::bidirectional_range); + static_assert(std::ranges::contiguous_range); + static_assert(std::ranges::common_range); + static_assert(std::ranges::viewable_range); + static_assert(!std::ranges::borrowed_range); + static_assert(std::ranges::random_access_range); + static_assert(std::ranges::sized_range); +}; + +int main() { + { + // std::optional does not meet range concepts. + test_concepts_disabled(std::optional{}); + test_concepts_disabled(std::optional{}); + test_concepts_disabled(std::optional{}); + test_concepts_disabled(std::optional{}); + test_concepts_disabled(std::optional{}); + test_concepts_disabled(std::optional{}); + } + + { + // beman::optional26::optional meets range concepts. + test_concepts_enabled(beman::optional26::optional{}); + test_concepts_enabled(beman::optional26::optional{}); + test_concepts_enabled(beman::optional26::optional{}); + test_concepts_enabled(beman::optional26::optional{}); + test_concepts_enabled(beman::optional26::optional{}); + test_concepts_enabled(beman::optional26::optional{}); + } + + return 0; +} + +// # build example: +// $ cmake --workflow --preset gcc-14 +// +// # run example: +// $ .build/gcc-14/examples/RelWithDebInfo/concept_checks diff --git a/examples/pythagorean_triples.cpp b/examples/pythagorean_triples.cpp index ce4b508b..b8987652 100644 --- a/examples/pythagorean_triples.cpp +++ b/examples/pythagorean_triples.cpp @@ -3,13 +3,14 @@ #include +#include #include #include #include #include int main() { - // Example from P3168R1: generate an infinite sequence of Pythagorean triples. + // Example from P3168R2: generate an infinite sequence of Pythagorean triples. // (x, y, z) is a Pythagorean triple if 1 <= x <= y <= z and x^2 + y^2 = z^2. constexpr auto yield_if = [](bool b, T x) -> beman::optional26::optional { return b ? beman::optional26::optional{std::move(x)} : beman::optional26::nullopt; diff --git a/examples/range_loop.cpp b/examples/range_loop.cpp index 6830a183..5b4c2445 100644 --- a/examples/range_loop.cpp +++ b/examples/range_loop.cpp @@ -5,7 +5,7 @@ #include int main() { - // Example from P3168R1: basic range loop over C++26 optional. + // Example from P3168R2: basic range loop over C++26 optional. beman::optional26::optional empty_opt{}; for ([[maybe_unused]] const auto& i : empty_opt) { diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index d9c9f462..31f2a6fc 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -1,4 +1,6 @@ +# cmake-format: off # extern/CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on add_subdirectory(googletest EXCLUDE_FROM_ALL) diff --git a/include/Beman/Optional26/optional.hpp b/include/Beman/Optional26/optional.hpp index c715c3c6..f3885a29 100644 --- a/include/Beman/Optional26/optional.hpp +++ b/include/Beman/Optional26/optional.hpp @@ -212,7 +212,7 @@ class optional; } // namespace beman::optional26 namespace std { -// Since P3168R1: Give std::optional Range Support. +// Since P3168R2: Give std::optional Range Support. template inline constexpr bool ranges::enable_view> = true; @@ -220,7 +220,7 @@ inline constexpr bool ranges::enable_view> = true template inline constexpr bool ranges::enable_borrowed_range> = true; -// Since P3168R1: Give std::optional Range Support. +// Since P3168R2: Give std::optional Range Support. #if defined(__cpp_lib_format_ranges) template inline constexpr auto format_kind> = range_format::disabled; @@ -318,7 +318,7 @@ class optional { public: using value_type = T; - // Since P3168R1: Give std::optional Range Support. + // Since P3168R2: Give std::optional Range Support. using iterator = detail::contiguous_iterator; // see [optional.iterators] using const_iterator = detail::contiguous_iterator; // see [optional.iterators] @@ -688,7 +688,7 @@ class optional { swap(engaged, rhs.engaged); } - // Since P3168R1: Give std::optional Range Support. + // Since P3168R2: Give std::optional Range Support. // [optional.iterators], iterator support constexpr iterator begin() noexcept { return iterator(has_value() ? std::addressof(value_) : nullptr); } constexpr const_iterator begin() const noexcept { @@ -941,7 +941,7 @@ class optional { using value_type = T&; // Since ${PAPER_NUMBER}: ${PAPER_TITLE}. // Note: P3168 and P2988 may have different flows inside LEWG/LWG. - // Implementation of the range support for optional reflects P3168R1 for now. + // Implementation of the range support for optional reflects P3168R2 for now. // [optional.iterators], iterator support using iterator = detail::contiguous_iterator; // see [optional.iterators] using const_iterator = detail::contiguous_iterator; // see [optional.iterators] @@ -1076,7 +1076,7 @@ class optional { // Since ${PAPER_NUMBER}: ${PAPER_TITLE}. // Note: P3168 and P2988 may have different flows inside LEWG/LWG. - // Implementation of the range support for optional reflects P3168R1 for now. + // Implementation of the range support for optional reflects P3168R2 for now. // [optional.iterators], iterator support constexpr iterator begin() noexcept { return iterator(has_value() ? value_ : nullptr); }; constexpr const_iterator begin() const noexcept { return const_iterator(has_value() ? value_ : nullptr); }; diff --git a/papers/P2988/README.md b/papers/P2988/README.md index b328d7c2..670f8354 100644 --- a/papers/P2988/README.md +++ b/papers/P2988/README.md @@ -9,6 +9,7 @@ SPDX-License-Identifier: 2.0 license with LLVM exceptions Compiling the paper requires a working LaTeX installation. See instructions for configuring your system at [C++ Standard Draft Sources](https://github.com/cplusplus/draft/blob/main/README.rst) The papers/ subdirectory has the LaTeX souces for P2988 and the supporting macro definitions. To build, run + ```shell make papers ``` diff --git a/src/Beman/CMakeLists.txt b/src/Beman/CMakeLists.txt index cd84ac80..45dfa2b8 100644 --- a/src/Beman/CMakeLists.txt +++ b/src/Beman/CMakeLists.txt @@ -1,4 +1,6 @@ +# cmake-format: off # src/Beman/CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on add_subdirectory(Optional26) diff --git a/src/Beman/Optional26/CMakeLists.txt b/src/Beman/Optional26/CMakeLists.txt index 9e2fe392..59e00a89 100644 --- a/src/Beman/Optional26/CMakeLists.txt +++ b/src/Beman/Optional26/CMakeLists.txt @@ -1,54 +1,47 @@ +# cmake-format: off # src/Beman/Optional26/CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on set(TARGET_LIBRARY "beman_optional26") add_library("${TARGET_LIBRARY}" STATIC "") -target_sources( - "${TARGET_LIBRARY}" - PRIVATE - optional.cpp - detail/iterator.cpp -) +target_sources("${TARGET_LIBRARY}" PRIVATE optional.cpp detail/iterator.cpp) include(GNUInstallDirs) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories("${TARGET_LIBRARY}" PUBLIC - $ - $ # /include/scratch +target_include_directories( + "${TARGET_LIBRARY}" + PUBLIC + $ + $ # /include/scratch ) install( TARGETS "${TARGET_LIBRARY}" EXPORT ${TARGETS_EXPORT_NAME}1 - DESTINATION ${CMAKE_INSTALL_LIBDIR} -) + DESTINATION ${CMAKE_INSTALL_LIBDIR}) string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_LOWER_PROJECT_NAME) install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_LOWER_PROJECT_NAME} - FILES_MATCHING PATTERN "*.hpp" -) + FILES_MATCHING + PATTERN "*.hpp") target_link_libraries("${TARGET_LIBRARY}") -## Tests +# Tests add_executable(optional_test "") target_sources( optional_test - PRIVATE - tests/optional.t.cpp - tests/optional_ref.t.cpp - tests/optional_monadic.t.cpp - tests/optional_range_support.t.cpp - tests/optional_ref_monadic.t.cpp - tests/detail/iterator.t.cpp -) + PRIVATE tests/optional.t.cpp tests/optional_ref.t.cpp + tests/optional_monadic.t.cpp tests/optional_range_support.t.cpp + tests/optional_ref_monadic.t.cpp tests/detail/iterator.t.cpp) target_link_libraries(optional_test "${TARGET_LIBRARY}") target_link_libraries(optional_test gtest) diff --git a/src/Beman/Optional26/tests/optional_range_support.t.cpp b/src/Beman/Optional26/tests/optional_range_support.t.cpp index 8093bb84..6dca54a6 100644 --- a/src/Beman/Optional26/tests/optional_range_support.t.cpp +++ b/src/Beman/Optional26/tests/optional_range_support.t.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception /** - * This file contains tests for the range support. Check P3168R1: "Give std::optional Range Support". + * This file contains tests for the range support. Check P3168R2: "Give std::optional Range Support". * * RangeSupportTest: test suite for the range support. * @@ -211,7 +211,7 @@ TEST(RangeSupportTest, LoopOverNonEmptyRange) { } TEST(RangeSupportTest, LoopOptionalAccess) { - // Example from P3168R1: should access the value from an optional object. + // Example from P3168R2: should access the value from an optional object. const int expected_value = 0xCAFEBABE; const auto get_optional = [&]() -> beman::optional26::optional { return expected_value; }; ASSERT_TRUE(get_optional().has_value()); @@ -222,7 +222,7 @@ TEST(RangeSupportTest, LoopOptionalAccess) { } TEST(RangeSupportTest, LoopOptionalAssignment) { - // Example from P3168R1: should mutate the value from an optional object. + // Example from P3168R2: should mutate the value from an optional object. const int initial_expected_value = 0xCAFEBABE; const int expected_value = 0xDEADBEEF; const auto get_optional = [&]() -> beman::optional26::optional { return initial_expected_value; }; @@ -239,7 +239,7 @@ TEST(RangeSupportTest, LoopOptionalAssignment) { } TEST(RangeSupportTest, RangeChainExample) { - // Example from P3168R1: start from a set of values, apply multiple range operations involving optional values. + // Example from P3168R2: start from a set of values, apply multiple range operations involving optional values. std::unordered_set s{1, 3, 7, 9}; const auto flt = [&](int i) -> beman::optional26::optional { if (s.contains(i)) { @@ -261,7 +261,7 @@ TEST(RangeSupportTest, RangeChainExample) { } TEST(RangeSupportTest, PythagoreanTriples) { - // Example from P3168R1: generate an infinite sequence of Pythagorean triples. + // Example from P3168R2: generate an infinite sequence of Pythagorean triples. // (x, y, z) is a Pythagorean triple if 1 <= x <= y <= z and x^2 + y^2 = z^2. constexpr auto yield_if = [](bool b, T x) -> beman::optional26::optional { return b ? beman::optional26::optional{std::move(x)} : beman::optional26::nullopt; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7be65236..5d1346f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,6 @@ +# cmake-format: off # src/CMakeLists.txt -*-makefile-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# cmake-format: on add_subdirectory(Beman)