diff --git a/.github/workflows/real-time-cpp-snippets.yml b/.github/workflows/real-time-cpp-snippets.yml index e046be3f1..75141ad6a 100644 --- a/.github/workflows/real-time-cpp-snippets.yml +++ b/.github/workflows/real-time-cpp-snippets.yml @@ -30,7 +30,7 @@ jobs: - name: host-snippets-all run: | cd ${{ matrix.chapter }} - ./${{ matrix.chapter }}.sh ${{ matrix.compiler }} c++20 + ./${{ matrix.chapter }}.sh ${{ matrix.compiler }} c++23 working-directory: ./code_snippets host-snippets-chapter06: runs-on: ubuntu-latest diff --git a/code_snippets/chapter03/chapter03.sh b/code_snippets/chapter03/chapter03.sh index 55c8870e3..47fcb013b 100755 --- a/code_snippets/chapter03/chapter03.sh +++ b/code_snippets/chapter03/chapter03.sh @@ -70,6 +70,10 @@ ${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address ${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter03_21-001_span.cpp -o ./bin/chapter03_21-001_span.exe ${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter03_22-001_mersenne_twister_19937.cpp -o ./bin/chapter03_22-001_mersenne_twister_19937.exe ${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter03_22-002_test_random_engines.cpp -o ./bin/chapter03_22-002_test_random_engines.exe +if [[ "${GCC}" == "g++" ]]; then +${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter03_23-001_expected_div_int.cpp -o ./bin/chapter03_23-001_expected_div_int.exe +${GCC} -std=${STD} -Wall -Wextra -Wpedantic -Werror -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter03_23-002_expected_div_integral.cpp -o ./bin/chapter03_23-002_expected_div_integral.exe +fi if [[ "${GCC}" == "g++" ]]; then ls -la \ @@ -112,7 +116,9 @@ ls -la \ ./bin/chapter03_20-002_alias.exe \ ./bin/chapter03_21-001_span.exe \ ./bin/chapter03_22-001_mersenne_twister_19937.exe \ -./bin/chapter03_22-002_test_random_engines.exe +./bin/chapter03_22-002_test_random_engines.exe \ +./bin/chapter03_23-001_expected_div_int.exe \ +./bin/chapter03_23-002_expected_div_integral.exe else ls -la \ ./bin/chapter03_01-001_declare_locals.exe \ diff --git a/code_snippets/chapter03/chapter03_23-001_expected_div_int.cpp b/code_snippets/chapter03/chapter03_23-001_expected_div_int.cpp new file mode 100644 index 000000000..5abb1b659 --- /dev/null +++ b/code_snippets/chapter03/chapter03_23-001_expected_div_int.cpp @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +// chapter03_23-001_expected_div_int.cpp + +enum class div_error +{ + div_none, + div_by_zero +}; + +auto safe_divide(int a, int b) noexcept -> std::expected +{ + if (b == 0) + { + return std::unexpected(div_error::div_by_zero); + } + else + { + return a / b; + } +} + +auto do_something() -> void +{ + // Division by zero. + auto result = safe_divide(10, 0); + + if (result.error() == div_error::div_by_zero) + { + std::cout << "Division by zero" << std::endl; + } + else + { + std::cout << "Division ok, result: " << *result << std::endl; + } + + result = safe_divide(10, 2); + + if (result.error() == div_error::div_by_zero) + { + std::cout << "Division by zero" << std::endl; + } + else + { + // Division ok, result: 5 + std::cout << "Division ok, result: " << *result << std::endl; + } +} + +auto main() -> int +{ + do_something(); +} diff --git a/code_snippets/chapter03/chapter03_23-002_expected_div_integral.cpp b/code_snippets/chapter03/chapter03_23-002_expected_div_integral.cpp new file mode 100644 index 000000000..7a3eb58b8 --- /dev/null +++ b/code_snippets/chapter03/chapter03_23-002_expected_div_integral.cpp @@ -0,0 +1,64 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +// chapter03_23-001_expected_div_int.cpp + +enum class div_error +{ + div_none, + div_by_zero +}; + +template +auto safe_divide(T a, T b) + -> std::enable_if_t, + std::expected> +{ + if (b == T { 0 }) + { + return std::unexpected(div_error::div_by_zero); + } + else + { + return a / b; + } +} + +auto do_something() -> void +{ + // Division by zero. + auto result = safe_divide(10U, 0U); + + if (result.error() == div_error::div_by_zero) + { + std::cout << "Division by zero" << std::endl; + } + else + { + std::cout << "Division ok, result: " << *result << std::endl; + } + + result = safe_divide(10, 2); + + if (result.error() == div_error::div_by_zero) + { + std::cout << "Division by zero" << std::endl; + } + else + { + // Division ok, result: 5 + std::cout << "Division ok, result: " << *result << std::endl; + } +} + +auto main() -> int +{ + do_something(); +} diff --git a/code_snippets/chapter05/chapter05.sh b/code_snippets/chapter05/chapter05.sh index a34c11a1d..895e56af6 100755 --- a/code_snippets/chapter05/chapter05.sh +++ b/code_snippets/chapter05/chapter05.sh @@ -36,7 +36,9 @@ $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_05-002_template_point.cpp -o ./bin/chapter05_05-002_template_point.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_05-003_template_point.cpp -o ./bin/chapter05_05-003_template_point.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_06-001_template_specialization.cpp -o ./bin/chapter05_06-001_template_specialization.exe -$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_06-002_template_point.cpp -o ./bin/chapter05_06-002_template_point.exe +$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_06-002_template_enable_if.cpp -o ./bin/chapter05_06-002_template_enable_if.exe +$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_06-003_template_concepts.cpp -o ./bin/chapter05_06-003_template_concepts.exe +$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_06-004_template_point.cpp -o ./bin/chapter05_06-004_template_point.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_07-001_led_static_polymorphism.cpp -o ./bin/chapter05_07-001_led_static_polymorphism.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_08-001_using_the_stl.cpp -o ./bin/chapter05_08-001_using_the_stl.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_08-002_using_the_stl_algo.cpp -o ./bin/chapter05_08-002_using_the_stl_algo.exe @@ -44,8 +46,8 @@ $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_09-001_factory_simple.cpp -o ./bin/chapter05_09-001_factory_simple.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_09-002_factory_variadic_template.cpp -o ./bin/chapter05_09-002_factory_variadic_template.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_10-001_metaprogram_factorial.cpp -o ./bin/chapter05_10-001_metaprogram_factorial.exe -$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_10-002_metaprogram_pow10.cpp -o ./bin/chapter05_10-002_metaprogram_pow10.exe -$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_10-003_metaprogram_inner_product.cpp -o ./bin/chapter05_10-003_metaprogram_inner_product.exe +$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_10-002_const_eval_pow10.cpp -o ./bin/chapter05_10-002_const_eval_pow10.exe +$GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_10-003_const_eval_inner_product.cpp -o ./bin/chapter05_10-003_const_eval_inner_product.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_11-001_tuple_things_simple.cpp -o ./bin/chapter05_11-001_tuple_things_simple.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_11-002_tuple_things_metaprogram.cpp -o ./bin/chapter05_11-002_tuple_things_metaprogram.exe $GCC -std=$STD -Wall -Wextra -Wpedantic -Werror -Wconversion -Wsign-conversion -O3 -m64 -fsanitize=address -fsanitize=shift -fsanitize=shift-exponent -fsanitize=shift-base -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=enum ./chapter05_11-003_tuple_things_metaprogram.cpp -o ./bin/chapter05_11-003_tuple_things_metaprogram.exe @@ -67,7 +69,9 @@ ls -la \ ./bin/chapter05_05-002_template_point.exe \ ./bin/chapter05_05-003_template_point.exe \ ./bin/chapter05_06-001_template_specialization.exe \ -./bin/chapter05_06-002_template_point.exe \ +./bin/chapter05_06-002_template_enable_if.exe \ +./bin/chapter05_06-003_template_concepts.exe \ +./bin/chapter05_06-004_template_point.exe \ ./bin/chapter05_07-001_led_static_polymorphism.exe \ ./bin/chapter05_08-001_using_the_stl.exe \ ./bin/chapter05_08-002_using_the_stl_algo.exe \ @@ -75,8 +79,8 @@ ls -la \ ./bin/chapter05_09-001_factory_simple.exe \ ./bin/chapter05_09-002_factory_variadic_template.exe \ ./bin/chapter05_10-001_metaprogram_factorial.exe \ -./bin/chapter05_10-002_metaprogram_pow10.exe \ -./bin/chapter05_10-003_metaprogram_inner_product.exe \ +./bin/chapter05_10-002_const_eval_pow10.exe \ +./bin/chapter05_10-003_const_eval_inner_product.exe \ ./bin/chapter05_11-001_tuple_things_simple.exe \ ./bin/chapter05_11-002_tuple_things_metaprogram.exe \ ./bin/chapter05_11-003_tuple_things_metaprogram.exe \ diff --git a/code_snippets/chapter05/chapter05_06-001_template_specialization.cpp b/code_snippets/chapter05/chapter05_06-001_template_specialization.cpp index 849dde956..7af36756c 100644 --- a/code_snippets/chapter05/chapter05_06-001_template_specialization.cpp +++ b/code_snippets/chapter05/chapter05_06-001_template_specialization.cpp @@ -1,52 +1,34 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2017 - 2018. +// Copyright Christopher Kormanyos 2017 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // #include +#include // chapter05_06-001_template_specialization.cpp -// The original add template function. +// Generic add template function. template -T add(const T& a, const T& b) +auto add(T a, T b) -> T { return a + b; } -// Make template specializations of add() with -// easy-to-detect errors for float, double -// and long double. - -template<> -float add(const float&, const float&) -{ - // Explicitly create an erroneous result! - return 0.0F; -} - +// Specialize add() for the type int. template<> -double add(const double&, const double&) +auto add(int a, int b) -> int { - // Explicitly create an erroneous result! - return 0.0; + return a + b; } -template<> -long double add(const long double&, - const long double&) +auto main() -> int { - // Explicitly create an erroneous result! - return 0.0L; -} + // Add with generic template to get result "abcxyz". + std::cout << add(std::string("abc"), std::string("xyz")) << std::endl; -int main() -{ - // 3 + // Add with specialized template to get result 3. std::cout << add(1, 2) << std::endl; - - // 0 - std::cout << add(1.0F, 2.0F) << std::endl; } diff --git a/code_snippets/chapter05/chapter05_06-002_template_enable_if.cpp b/code_snippets/chapter05/chapter05_06-002_template_enable_if.cpp new file mode 100644 index 000000000..cc750fcb3 --- /dev/null +++ b/code_snippets/chapter05/chapter05_06-002_template_enable_if.cpp @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2017 - 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +// chapter05_06-002_template_enable_if.cpp + +// The original add template function. +template +auto add(T a, T b) noexcept + -> std::enable_if_t, T> +{ + return a + b; +} + +// Easy-to-detect errors for float, double +// and long double. + +template +auto add(T, T) noexcept + -> std::enable_if_t, T> +{ + // Explicitly create an erroneous result! + return T { 0.0F }; +} + +auto main() -> int; + +auto main() -> int +{ + // 3 + std::cout << add(1, 2) << std::endl; + + // 0 + std::cout << add(1.0F, 2.0F) << std::endl; +} diff --git a/code_snippets/chapter05/chapter05_06-003_template_concepts.cpp b/code_snippets/chapter05/chapter05_06-003_template_concepts.cpp new file mode 100644 index 000000000..238047168 --- /dev/null +++ b/code_snippets/chapter05/chapter05_06-003_template_concepts.cpp @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include +#include + +// chapter05_06-003_template_concepts.cpp + +// Generic add template function. +template +auto add(T a, T b) -> T +{ + return a + b; +} + +template +requires std::integral +auto add(T a, T b) -> T +{ + return a + b; +} + +auto do_something() -> void +{ + // 3U + const unsigned c { add(1U, 2U) }; + + std::cout << c << std::endl; + + // abcxyz + const std::string str + { add(std::string("abc"), std::string("xyz")) }; + + std::cout << str << std::endl; +} + +auto main() -> int +{ + do_something(); +} diff --git a/code_snippets/chapter05/chapter05_06-002_template_point.cpp b/code_snippets/chapter05/chapter05_06-004_template_point.cpp similarity index 93% rename from code_snippets/chapter05/chapter05_06-002_template_point.cpp rename to code_snippets/chapter05/chapter05_06-004_template_point.cpp index 80a5e347f..6ddeb2a03 100644 --- a/code_snippets/chapter05/chapter05_06-002_template_point.cpp +++ b/code_snippets/chapter05/chapter05_06-004_template_point.cpp @@ -1,11 +1,11 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2017 - 2023. +// Copyright Christopher Kormanyos 2017 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -// chapter05_06-002_template_point.cpp +// chapter05_06-004_template_point.cpp #include #include diff --git a/code_snippets/chapter05/chapter05_10-002_const_eval_pow10.cpp b/code_snippets/chapter05/chapter05_10-002_const_eval_pow10.cpp new file mode 100644 index 000000000..c58ab3039 --- /dev/null +++ b/code_snippets/chapter05/chapter05_10-002_const_eval_pow10.cpp @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2018 - 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// chapter05_10-002_const_eval_pow10.cpp + +#include +#include +#include +#include + +extern std::uint32_t p_nonconst; + +template +constexpr auto pow10(T p) + -> std::enable_if_t, T>; + +template +constexpr auto pow10(T p) + -> std::enable_if_t, T> +{ + if(std::is_constant_evaluated()) + { + constexpr T ten { 10 }; + + return p == 0 ? T { 1 } + : p == 1 ? ten + : ten * pow10(T { p - 1U }); + } + else + { + using std::pow; + + return static_cast(pow(10, p)); + } +} + +auto main() -> int +{ + constexpr std::uint32_t p { UINT64_C(6) }; + + // This is constexpr. + constexpr std::uint32_t million { pow10(p) }; + + static_assert(million == UINT32_C(1'000'000), + "Error: wrong result for pow10 function."); + + // This is not constexpr. + const std::uint32_t million_nonconst { pow10(p_nonconst) }; + + std::cout << "million: " << million << std::endl; + std::cout << "million_nonconst: " << million_nonconst << std::endl; +} + +std::uint32_t p_nonconst { UINT64_C(6) }; diff --git a/code_snippets/chapter05/chapter05_10-002_metaprogram_pow10.cpp b/code_snippets/chapter05/chapter05_10-002_metaprogram_pow10.cpp deleted file mode 100644 index 1cff2dee0..000000000 --- a/code_snippets/chapter05/chapter05_10-002_metaprogram_pow10.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2018 - 2019. -// Distributed under the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -// chapter05_10-002_metaprogram_pow10.cpp - -#include -#include - -template -constexpr std::uint32_t pow10() -{ - static_assert(n <= 9U, "Error: n is limited to 9 or less."); - - return pow10() * UINT32_C(10); -}; - -template<> -constexpr std::uint32_t pow10() -{ - return UINT32_C(1); -}; - -int main() -{ - // 1,000,000 - constexpr std::uint32_t million = pow10<6U>(); - - std::cout << million << std::endl; -} diff --git a/code_snippets/chapter05/chapter05_10-003_const_eval_inner_product.cpp b/code_snippets/chapter05/chapter05_10-003_const_eval_inner_product.cpp new file mode 100644 index 000000000..422a7b645 --- /dev/null +++ b/code_snippets/chapter05/chapter05_10-003_const_eval_inner_product.cpp @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2018 - 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// chapter05_10-003_const_eval_inner_product.cpp + +#include +#include +#include + +// chapter05_10-003_const_eval_inner_product.cpp + +constexpr std::array u +{ + { 1U, 2U, 3U } +}; + +constexpr std::array v +{ + { 4U, 5U, 6U } +}; + +// The result is 32. +constexpr unsigned w +{ + std::inner_product(u.cbegin(), + u.cend(), + v.cbegin(), + 0U) +}; + +static_assert(w == 32U, "Error in inner_produce"); + +auto main() -> int +{ + std::cout << "Result of inner product is: " << w << std::endl; +} diff --git a/code_snippets/chapter05/chapter05_10-003_metaprogram_inner_product.cpp b/code_snippets/chapter05/chapter05_10-003_metaprogram_inner_product.cpp deleted file mode 100644 index 7a17cdb18..000000000 --- a/code_snippets/chapter05/chapter05_10-003_metaprogram_inner_product.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2018. -// Distributed under the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -// chapter05_10-003_metaprogram_inner_product.cpp - -#include -#include -#include -#include - -template -struct inner_product -{ - template - static result_type sum(iterator_left u, - iterator_right v, - const result_type& init) - { - // Add (u[M] * v[M]) recursively. - const result_type uvm - = *(u + M) * result_type(*(v + M)); - - return uvm - + inner_product::sum(u, v, init); - } -}; - -template -struct inner_product -{ - template - static result_type sum(iterator_left, - iterator_right, - const result_type&) - { - // N'th specialization terminates the recursion. - return result_type(0); - } -}; - -int main() -{ - constexpr std::array u - { - { 1U, 2U, 3U } - }; - - constexpr std::array v - { - { 4U, 5U, 6U } - }; - - // The result is 32. - const unsigned w = - inner_product<3U>::sum(u.cbegin(), - v.cbegin(), - 0U); - - std::cout << "Result of inner product is: " << w << std::endl; -} diff --git a/examples/chapter02_02/chapter02_02.vcxproj b/examples/chapter02_02/chapter02_02.vcxproj index 40036ff57..a773fe7b4 100644 --- a/examples/chapter02_02/chapter02_02.vcxproj +++ b/examples/chapter02_02/chapter02_02.vcxproj @@ -45,10 +45,10 @@ - build.bat $(SolutionDir)tools\Util\msys64\usr\local\gcc-11.2.0-avr\bin avr + build.bat $(SolutionDir)tools\Util\msys64\usr\local\gcc-15.1.0-avr\bin avr $(OutDir)led.hex del /Q bin\*.* - build.bat $(SolutionDir)tools\Util\msys64\usr\local\gcc-11.2.0-avr\bin avr + build.bat $(SolutionDir)tools\Util\msys64\usr\local\gcc-15.1.0-avr\bin avr $(SolutionDir)bin\ @@ -65,6 +65,9 @@ $(OutDir)$(Configuration).log + + stdcpp20 + diff --git a/examples/chapter02_02/mcal_reg.h b/examples/chapter02_02/mcal_reg.h index 7148876e1..a8eef6cb6 100644 --- a/examples/chapter02_02/mcal_reg.h +++ b/examples/chapter02_02/mcal_reg.h @@ -10,21 +10,19 @@ #include - namespace mcal - { - namespace reg - { - constexpr std::uint8_t portb { UINT8_C(0x25U) }; + namespace mcal::reg { - constexpr std::uint8_t bval0 { UINT8_C(0x01) }; - constexpr std::uint8_t bval1 { UINT8_C(0x01) << 1U }; - constexpr std::uint8_t bval2 { UINT8_C(0x01) << 2U }; - constexpr std::uint8_t bval3 { UINT8_C(0x01) << 3U }; - constexpr std::uint8_t bval4 { UINT8_C(0x01) << 4U }; - constexpr std::uint8_t bval5 { UINT8_C(0x01) << 5U }; - constexpr std::uint8_t bval6 { UINT8_C(0x01) << 6U }; - constexpr std::uint8_t bval7 { UINT8_C(0x01) << 7U }; - } - } + constexpr std::uint8_t portb { UINT8_C(0x25U) }; + + constexpr std::uint8_t bval0 { UINT8_C(0x01) }; + constexpr std::uint8_t bval1 { UINT8_C(0x01) << 1U }; + constexpr std::uint8_t bval2 { UINT8_C(0x01) << 2U }; + constexpr std::uint8_t bval3 { UINT8_C(0x01) << 3U }; + constexpr std::uint8_t bval4 { UINT8_C(0x01) << 4U }; + constexpr std::uint8_t bval5 { UINT8_C(0x01) << 5U }; + constexpr std::uint8_t bval6 { UINT8_C(0x01) << 6U }; + constexpr std::uint8_t bval7 { UINT8_C(0x01) << 7U }; + + } // namespace mcal::reg #endif // MCAL_REG_2011_11_04_H diff --git a/examples/chapter02_06/chapter02_06.vcxproj b/examples/chapter02_06/chapter02_06.vcxproj index 8d86bb5eb..a773fe7b4 100644 --- a/examples/chapter02_06/chapter02_06.vcxproj +++ b/examples/chapter02_06/chapter02_06.vcxproj @@ -65,6 +65,9 @@ $(OutDir)$(Configuration).log + + stdcpp20 + diff --git a/examples/chapter02_06/mcal_reg.h b/examples/chapter02_06/mcal_reg.h index 7148876e1..a8eef6cb6 100644 --- a/examples/chapter02_06/mcal_reg.h +++ b/examples/chapter02_06/mcal_reg.h @@ -10,21 +10,19 @@ #include - namespace mcal - { - namespace reg - { - constexpr std::uint8_t portb { UINT8_C(0x25U) }; + namespace mcal::reg { - constexpr std::uint8_t bval0 { UINT8_C(0x01) }; - constexpr std::uint8_t bval1 { UINT8_C(0x01) << 1U }; - constexpr std::uint8_t bval2 { UINT8_C(0x01) << 2U }; - constexpr std::uint8_t bval3 { UINT8_C(0x01) << 3U }; - constexpr std::uint8_t bval4 { UINT8_C(0x01) << 4U }; - constexpr std::uint8_t bval5 { UINT8_C(0x01) << 5U }; - constexpr std::uint8_t bval6 { UINT8_C(0x01) << 6U }; - constexpr std::uint8_t bval7 { UINT8_C(0x01) << 7U }; - } - } + constexpr std::uint8_t portb { UINT8_C(0x25U) }; + + constexpr std::uint8_t bval0 { UINT8_C(0x01) }; + constexpr std::uint8_t bval1 { UINT8_C(0x01) << 1U }; + constexpr std::uint8_t bval2 { UINT8_C(0x01) << 2U }; + constexpr std::uint8_t bval3 { UINT8_C(0x01) << 3U }; + constexpr std::uint8_t bval4 { UINT8_C(0x01) << 4U }; + constexpr std::uint8_t bval5 { UINT8_C(0x01) << 5U }; + constexpr std::uint8_t bval6 { UINT8_C(0x01) << 6U }; + constexpr std::uint8_t bval7 { UINT8_C(0x01) << 7U }; + + } // namespace mcal::reg #endif // MCAL_REG_2011_11_04_H