Something went wrong. Try again.
A Tour of C++ for experienced programmers, as if C++26 is the only version that ever existed.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112# Registers book examples as real compiled targets.## book_example(file [EXPECT "regex"]) — a runnable, fully-checked example.# Builds with the full warning set plus -Werror (when BOOK_WERROR is ON) and# clang-tidy; runs under CTest (with ASan/UBSan when BOOK_SANITIZE is ON).# If EXPECT is given, the run also must print output matching the regex.# -Werror turns every warning into a hard error so a clean example stays# clean. It applies only to book_example: demos and gaps still emit their# teaching warnings without failing the build.## book_demo(file) — a deliberately-wrong teaching demo (dangling pointer,# ODR violation, fossil code). Compiles with warnings visible (the warning# is the exhibit), clang-tidy off, no sanitizer, no CTest run. The expected# diagnostic is pasted in a comment at the top of the file by hand.## book_gap(file feature) — standard C++26 feature without shipping Clang# support. The target exists only with -DBOOK_ENABLE_GAPS=ON and may# legitimately fail to compile. Never built by default.
# The lifetime-safety analysis flag is not stabilized: prefer -Wlifetime-safety# (Clang 23+ direction), fall back to the cc1 form -Xclang -fexperimental-lifetime-safety# (Clang 22, emits few diagnostics). Unknown -W options must not pass the probe,# hence -Werror=unknown-warning-option for the first check.include(CheckCXXCompilerFlag)include(CheckCXXSourceCompiles)set(CMAKE_REQUIRED_FLAGS "-Werror=unknown-warning-option")check_cxx_compiler_flag("-Wlifetime-safety" BOOK_HAVE_WLIFETIME_SAFETY)set(CMAKE_REQUIRED_FLAGS "-Xclang -fexperimental-lifetime-safety")check_cxx_source_compiles("int main() { return 0; }" BOOK_HAVE_EXPERIMENTAL_LIFETIME)unset(CMAKE_REQUIRED_FLAGS)
if(BOOK_HAVE_WLIFETIME_SAFETY) set(BOOK_LIFETIME_FLAG "-Wlifetime-safety")elseif(BOOK_HAVE_EXPERIMENTAL_LIFETIME) set(BOOK_LIFETIME_FLAG "-Xclang;-fexperimental-lifetime-safety") message(STATUS "lifetime-safety analysis: experimental cc1 form (Clang 22)")else() message(WARNING "this compiler has no lifetime-safety analysis; the committee is incomplete") set(BOOK_LIFETIME_FLAG "")endif()
set(BOOK_WARNING_FLAGS -Wall -Wextra -Wpedantic -Wconversion -Wshadow ${BOOK_LIFETIME_FLAG})
function(_book_add_target out_var file) get_filename_component(name "${file}" NAME_WE) add_executable(${name} "${file}") set(${out_var} ${name} PARENT_SCOPE)endfunction()
function(book_example file) cmake_parse_arguments(arg "" "EXPECT" "" ${ARGN}) _book_add_target(t "${file}") target_compile_options(${t} PRIVATE ${BOOK_WARNING_FLAGS}) if(BOOK_WERROR) target_compile_options(${t} PRIVATE -Werror) endif() if(BOOK_SANITIZE) target_compile_options(${t} PRIVATE -fsanitize=address -fsanitize=undefined) target_link_options(${t} PRIVATE -fsanitize=address -fsanitize=undefined) endif() add_test(NAME ${t}_run COMMAND ${t}) if(arg_EXPECT) set_tests_properties(${t}_run PROPERTIES PASS_REGULAR_EXPRESSION "${arg_EXPECT}") endif()endfunction()
function(book_demo file) _book_add_target(t "${file}") target_compile_options(${t} PRIVATE ${BOOK_WARNING_FLAGS}) set_target_properties(${t} PROPERTIES CXX_CLANG_TIDY "")endfunction()
function(book_gap file feature) if(BOOK_ENABLE_GAPS) message(STATUS "gap example enabled: ${file} (feature: ${feature})") _book_add_target(t "${file}") target_compile_options(${t} PRIVATE ${BOOK_WARNING_FLAGS}) set_target_properties(${t} PROPERTIES CXX_CLANG_TIDY "") endif()endfunction()
# book_compile_error(file expected_regex) — verifies that a file fails to# compile and that the compiler diagnostic matches expected_regex. This is a# configure-time check via try_compile, so it runs once per configure, not# as a build target. If the file unexpectedly compiles, or the expected# diagnostic is missing, configure fails with a FATAL_ERROR.function(book_compile_error file expected_regex) get_filename_component(name "${file}" NAME_WE) set(bindir "${CMAKE_CURRENT_BINARY_DIR}/compile_error_${name}") file(MAKE_DIRECTORY "${bindir}") try_compile( BOOK_COMPILE_ERROR_${name} "${bindir}" "${CMAKE_CURRENT_SOURCE_DIR}/${file}" OUTPUT_VARIABLE BOOK_COMPILE_ERROR_OUTPUT CXX_STANDARD 26 CXX_STANDARD_REQUIRED ON ) if(BOOK_COMPILE_ERROR_${name}) message(FATAL_ERROR "book_compile_error: ${file} unexpectedly compiled; expected it to fail") endif() if(NOT BOOK_COMPILE_ERROR_OUTPUT MATCHES "${expected_regex}") message(FATAL_ERROR "book_compile_error: ${file} failed to compile but the diagnostic did " "not match '${expected_regex}'. Actual output:\n${BOOK_COMPILE_ERROR_OUTPUT}") endif() message(STATUS "compile error verified: ${file} (matches '${expected_regex}')")endfunction()