diff --git a/CMakeLists.txt b/CMakeLists.txt index 452671fd..76788888 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(stl-concepts VERSION 0.0.0 LANGUAGES CXX) +project(beman_optional26 VERSION 0.0.0 LANGUAGES CXX) enable_testing() @@ -8,6 +8,7 @@ set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets) add_subdirectory(extern) add_subdirectory(src) +add_subdirectory(examples) include(GNUInstallDirs) diff --git a/README.md b/README.md index 647c9c5d..8bcecb66 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Compiling the paper requires a working LaTeX installation. See instructions for #### 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 `example` library, ready to package: +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 cmake --workflow --preset gcc-14 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..aff0f99f --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,32 @@ +set(BEMAN_OPTIONAL26_LIBRARY "beman_optional26") + +include(GNUInstallDirs) + +# List of all buildable examples. +set(EXAMPLES + sample + range_loop + optional_ref +) + +foreach(EXAMPLE ${EXAMPLES}) + # Add example executable. + add_executable(${EXAMPLE} "") + + # Add example source file. + target_sources( + ${EXAMPLE} + PRIVATE + ${EXAMPLE}.cpp + ) + + # Link example with the library. + target_link_libraries(${EXAMPLE} "${BEMAN_OPTIONAL26_LIBRARY}") + + # Install . + install( + TARGETS ${EXAMPLE} + EXPORT ${TARGETS_EXPORT_NAME} + DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endforeach() diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..b43db0be --- /dev/null +++ b/examples/README.md @@ -0,0 +1,42 @@ +# Beman.Optional26 Examples + +List of usage examples for `Beman.Optional26`. + +## Sample + +Check [sample](sample.cpp) for basic `Beman.Optional26` library usage. + +Build and run instructions: +```shell +# build +$ cmake --workflow --preset gcc-14 + +# run sample +$ .build/gcc-14/examples/RelWithDebInfo/sample +empty_opt is empty! +opt = 26 +``` + +## Range Support (P3168R1) + +Range support added in [*Give std::optional Range Support* (P3168R1)](https://wg21.link/P3168R1) examples: +* [./range_loop.cpp](./range_loop.cpp) + + +Build and run instructions: + +```shell +# build +$ cmake --workflow --preset gcc-14 + +# run range_loop +$ .build/gcc-14/examples/RelWithDebInfo/range_loop + # note: 1st log (empty_opt) is missing from console! +"for each loop" over C++26 optional: opt = 26 # 2nd log (non empty opt) +``` + +## Optional Reference (P2988R5) + +Reference support added in [*std::optional*(P2988R5)](https://wg21.link/P2988R5) examples: + +* [./optional_ref.cpp](./optional_ref.cpp) diff --git a/src/examples/before_after.cpp b/examples/optional_ref.cpp similarity index 87% rename from src/examples/before_after.cpp rename to examples/optional_ref.cpp index c505ca47..aaa25dfc 100644 --- a/src/examples/before_after.cpp +++ b/examples/optional_ref.cpp @@ -1,4 +1,4 @@ -#include +#include #include @@ -12,7 +12,7 @@ auto find_cat_old(std::string) -> Cat* { return nullptr; } auto find_cat_new(std::string) -> optional { return optional{}; } -Cat* doit_old(Cat& cat) { return &cat; } +Cat* doit_old(Cat& cat) { return &cat; } optional doit(Cat& cat) { return optional{cat}; } Cat* before1() { diff --git a/examples/range_loop.cpp b/examples/range_loop.cpp new file mode 100644 index 00000000..27a827a2 --- /dev/null +++ b/examples/range_loop.cpp @@ -0,0 +1,17 @@ +#include +#include + +int main() { + beman::optional::optional empty_opt{}; + for ([[maybe_unused]] const auto& i : empty_opt) { + // Should not see this in console. + std::cout << "\"for each loop\" over C++26 optional: empty_opt\n"; + } + + beman::optional::optional opt{26}; + for (const auto& i : opt) { + // Should see this in console. + std::cout << "\"for each loop\" over C++26 optional: opt = " << i << "\n"; + } + return 0; +} diff --git a/examples/sample.cpp b/examples/sample.cpp new file mode 100644 index 00000000..3d3499bb --- /dev/null +++ b/examples/sample.cpp @@ -0,0 +1,16 @@ +#include +#include + +int main() { + beman::optional::optional empty_opt{}; + if (!empty_opt) { + std::cout << "empty_opt is empty!\n"; + } + + beman::optional::optional opt{26}; + if (opt) { + std::cout << "opt = " << *opt << "\n"; + } + + return 0; +} diff --git a/src/beman/optional/optional.hpp b/include/Beman/Optional26/optional.hpp similarity index 99% rename from src/beman/optional/optional.hpp rename to include/Beman/Optional26/optional.hpp index baf48cd0..3b8d0f0f 100644 --- a/src/beman/optional/optional.hpp +++ b/include/Beman/Optional26/optional.hpp @@ -1,6 +1,6 @@ // beman/optional/optional.h -*-C++-*- -#ifndef INCLUDED_BEMAN_OPTIONAL_OPTIONAL -#define INCLUDED_BEMAN_OPTIONAL_OPTIONAL +#ifndef BEMAN_OPTIONAL26_OPTIONAL +#define BEMAN_OPTIONAL26_OPTIONAL /* 22.5.2 Header synopsis[optional.syn] diff --git a/src/beman/CMakeLists.txt b/src/Beman/CMakeLists.txt similarity index 100% rename from src/beman/CMakeLists.txt rename to src/Beman/CMakeLists.txt diff --git a/src/beman/optional/CMakeLists.txt b/src/Beman/optional/CMakeLists.txt similarity index 69% rename from src/beman/optional/CMakeLists.txt rename to src/Beman/optional/CMakeLists.txt index 70649f01..9ca5065e 100644 --- a/src/beman/optional/CMakeLists.txt +++ b/src/Beman/optional/CMakeLists.txt @@ -1,23 +1,25 @@ -add_library(optional STATIC "") +set(TARGET_LIBRARY "beman_optional26") + +add_library("${TARGET_LIBRARY}" STATIC "") target_sources( - optional + "${TARGET_LIBRARY}" PRIVATE optional.cpp ) include(GNUInstallDirs) -target_include_directories(optional PUBLIC - $ +target_include_directories("${TARGET_LIBRARY}" PUBLIC + $ $ # /include/scratch - ) +) install( - TARGETS optional + TARGETS "${TARGET_LIBRARY}" EXPORT ${TARGETS_EXPORT_NAME}1 DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) +) string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_LOWER_PROJECT_NAME) @@ -25,9 +27,9 @@ install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_LOWER_PROJECT_NAME} FILES_MATCHING PATTERN "*.h" - ) +) -target_link_libraries(optional) +target_link_libraries("${TARGET_LIBRARY}") ## Tests add_executable(optional_test "") @@ -41,7 +43,7 @@ target_sources( optional_ref_monadic.t.cpp ) -target_link_libraries(optional_test optional) +target_link_libraries(optional_test "${TARGET_LIBRARY}") target_link_libraries(optional_test gtest) target_link_libraries(optional_test gtest_main) diff --git a/src/Beman/optional/optional.cpp b/src/Beman/optional/optional.cpp new file mode 100644 index 00000000..f9a0eeb8 --- /dev/null +++ b/src/Beman/optional/optional.cpp @@ -0,0 +1 @@ +#include diff --git a/src/beman/optional/optional.t.cpp b/src/Beman/optional/optional.t.cpp similarity index 99% rename from src/beman/optional/optional.t.cpp rename to src/Beman/optional/optional.t.cpp index 255c8d9e..9da8715d 100644 --- a/src/beman/optional/optional.t.cpp +++ b/src/Beman/optional/optional.t.cpp @@ -1,6 +1,6 @@ -#include +#include -#include // test 2nd include OK +#include // test 2nd include OK #include #include diff --git a/src/beman/optional/optional_monadic.t.cpp b/src/Beman/optional/optional_monadic.t.cpp similarity index 85% rename from src/beman/optional/optional_monadic.t.cpp rename to src/Beman/optional/optional_monadic.t.cpp index e318f2ea..79a1c6a7 100644 --- a/src/beman/optional/optional_monadic.t.cpp +++ b/src/Beman/optional/optional_monadic.t.cpp @@ -1,6 +1,4 @@ -#include - -#include +#include #include @@ -9,7 +7,7 @@ constexpr beman::optional::optional get_opt_int(int) { return 42; } TEST(OptionalMonadicTest, Transform) { - // lhs is empty + // lhs is empty beman::optional::optional o1; auto o1r = o1.transform([](int i) { return i + 2; }); static_assert((std::is_same>::value)); @@ -85,27 +83,26 @@ TEST(OptionalMonadicTest, Transform) { } -TEST(OptionalMonadicTest, TransformConstexpr) { - - // test each overload in turn - constexpr beman::optional::optional o16 = 42; - constexpr auto o16r = o16.transform(get_int); - static_assert(*o16r == 42); - - constexpr beman::optional::optional o20 = 42; - constexpr auto o20r = std::move(o20).transform(get_int); - static_assert(*o20r == 42); - - constexpr beman::optional::optional o32 = beman::optional::nullopt; - constexpr auto o32r = o32.transform(get_int); - static_assert(!o32r); - constexpr beman::optional::optional o36 = beman::optional::nullopt; - constexpr auto o36r = std::move(o36).transform(get_int); - static_assert(!o36r); + TEST(OptionalMonadicTest, TransformConstexpr) { + // test each overload in turn + constexpr beman::optional::optional o16 = 42; + constexpr auto o16r = o16.transform(get_int); + static_assert(*o16r == 42); + + constexpr beman::optional::optional o20 = 42; + constexpr auto o20r = std::move(o20).transform(get_int); + static_assert(*o20r == 42); + + constexpr beman::optional::optional o32 = beman::optional::nullopt; + constexpr auto o32r = o32.transform(get_int); + static_assert(!o32r); + constexpr beman::optional::optional o36 = beman::optional::nullopt; + constexpr auto o36r = std::move(o36).transform(get_int); + static_assert(!o36r); } TEST(OptionalMonadicTest, Transform2) { - // lhs is empty + // lhs is empty beman::optional::optional o1; auto o1r = o1.transform([](int i) { return i + 2; }); static_assert((std::is_same>::value)); @@ -173,23 +170,22 @@ TEST(OptionalMonadicTest, Transform2) { EXPECT_TRUE(!o36r); } -TEST(OptionalMonadicTest, TransformConstxpr) - { - // test each overload in turn - constexpr beman::optional::optional o16 = 42; - constexpr auto o16r = o16.transform(get_int); - static_assert(*o16r == 42); - - constexpr beman::optional::optional o20 = 42; - constexpr auto o20r = std::move(o20).transform(get_int); - static_assert(*o20r == 42); - - constexpr beman::optional::optional o32 = beman::optional::nullopt; - constexpr auto o32r = o32.transform(get_int); - static_assert(!o32r); - constexpr beman::optional::optional o36 = beman::optional::nullopt; - constexpr auto o36r = std::move(o36).transform(get_int); - static_assert(!o36r); + TEST(OptionalMonadicTest, TransformConstxpr) { + // test each overload in turn + constexpr beman::optional::optional o16 = 42; + constexpr auto o16r = o16.transform(get_int); + static_assert(*o16r == 42); + + constexpr beman::optional::optional o20 = 42; + constexpr auto o20r = std::move(o20).transform(get_int); + static_assert(*o20r == 42); + + constexpr beman::optional::optional o32 = beman::optional::nullopt; + constexpr auto o32r = o32.transform(get_int); + static_assert(!o32r); + constexpr beman::optional::optional o36 = beman::optional::nullopt; + constexpr auto o36r = std::move(o36).transform(get_int); + static_assert(!o36r); } TEST(OptionalMonadicTest, and_then) diff --git a/src/beman/optional/optional_ref.t.cpp b/src/Beman/optional/optional_ref.t.cpp similarity index 99% rename from src/beman/optional/optional_ref.t.cpp rename to src/Beman/optional/optional_ref.t.cpp index 65b36e36..3591256b 100644 --- a/src/beman/optional/optional_ref.t.cpp +++ b/src/Beman/optional/optional_ref.t.cpp @@ -1,6 +1,4 @@ -#include - -#include +#include #include diff --git a/src/beman/optional/optional_ref_monadic.t.cpp b/src/Beman/optional/optional_ref_monadic.t.cpp similarity index 99% rename from src/beman/optional/optional_ref_monadic.t.cpp rename to src/Beman/optional/optional_ref_monadic.t.cpp index bb14ff52..9d9f9fda 100644 --- a/src/beman/optional/optional_ref_monadic.t.cpp +++ b/src/Beman/optional/optional_ref_monadic.t.cpp @@ -1,6 +1,4 @@ -#include - -#include +#include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b654f63..3a085d51 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1 @@ -add_subdirectory(beman) -add_subdirectory(examples) +add_subdirectory(Beman) diff --git a/src/beman/optional/optional.cpp b/src/beman/optional/optional.cpp deleted file mode 100644 index c27e0893..00000000 --- a/src/beman/optional/optional.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt deleted file mode 100644 index d4aed689..00000000 --- a/src/examples/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ - -include(GNUInstallDirs) - -add_executable(main "") - -target_sources( - main - PRIVATE - main.cpp) - -target_link_libraries(main optional) - -add_executable(before_after "") - -target_sources( - before_after - PRIVATE - before_after.cpp) - -target_link_libraries(before_after optional) - -install( - TARGETS main - EXPORT ${TARGETS_EXPORT_NAME} - DESTINATION ${CMAKE_INSTALL_BINDIR} - ) diff --git a/src/examples/main.cpp b/src/examples/main.cpp deleted file mode 100644 index 2ea83fa3..00000000 --- a/src/examples/main.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include - -int main() { -}