From 0c9a0449c53ae07494287268f9a3fcaf8179cc6e Mon Sep 17 00:00:00 2001 From: ckormanyos Date: Sat, 14 Dec 2024 12:53:08 +0100 Subject: [PATCH] Update and test example chapter11_7 --- examples/chapter11_07/chapter11_07.cppproj | 178 +- examples/chapter11_07/chapter11_07.vcxproj | 83 +- .../chapter11_07/chapter11_07.vcxproj.filters | 267 ++- examples/chapter11_07/src/app/led/app_led.cpp | 7 +- examples/chapter11_07/src/app/led/app_led.h | 8 +- .../src/math/checksums/crc/crc32.h | 66 + .../chapter11_07/src/mcal/avr/mcal_cpu.cpp | 4 +- examples/chapter11_07/src/mcal/avr/mcal_cpu.h | 12 +- .../chapter11_07/src/mcal/avr/mcal_gpt.cpp | 78 +- examples/chapter11_07/src/mcal/avr/mcal_gpt.h | 22 +- .../chapter11_07/src/mcal/avr/mcal_irq.cpp | 4 +- examples/chapter11_07/src/mcal/avr/mcal_irq.h | 16 +- .../chapter11_07/src/mcal/avr/mcal_led.cpp | 6 +- examples/chapter11_07/src/mcal/avr/mcal_led.h | 12 +- .../src/mcal/avr/mcal_memory_progmem.h | 10 +- .../chapter11_07/src/mcal/avr/mcal_osc.cpp | 4 +- examples/chapter11_07/src/mcal/avr/mcal_osc.h | 12 +- .../chapter11_07/src/mcal/avr/mcal_port.cpp | 4 +- .../chapter11_07/src/mcal/avr/mcal_port.h | 26 +- examples/chapter11_07/src/mcal/avr/mcal_reg.h | 112 +- .../chapter11_07/src/mcal/avr/mcal_wdg.cpp | 39 +- examples/chapter11_07/src/mcal/avr/mcal_wdg.h | 28 +- .../src/mcal/mcal_gcc_cxx_completion.cpp | 8 +- .../chapter11_07/src/mcal_led/mcal_led_base.h | 22 +- .../mcal_led/mcal_led_boolean_state_base.h | 23 +- .../src/mcal_led/mcal_led_console.h | 41 +- .../chapter11_07/src/mcal_led/mcal_led_port.h | 20 +- .../src/mcal_led/mcal_led_port_inverted.h | 20 +- .../chapter11_07/src/mcal_led/mcal_led_pwm.h | 34 +- .../chapter11_07/src/util/STD_LIBC/memory.c | 87 + .../chapter11_07/src/util/STD_LIBC/memory.cpp | 83 - examples/chapter11_07/src/util/STL/algorithm | 191 +- examples/chapter11_07/src/util/STL/array | 73 +- examples/chapter11_07/src/util/STL/cassert | 13 + examples/chapter11_07/src/util/STL/cerrno | 13 + examples/chapter11_07/src/util/STL/charconv | 47 + examples/chapter11_07/src/util/STL/chrono | 13 +- examples/chapter11_07/src/util/STL/cinttypes | 23 + examples/chapter11_07/src/util/STL/ciso646 | 15 + examples/chapter11_07/src/util/STL/cmath | 902 ++++++--- examples/chapter11_07/src/util/STL/complex | 14 +- examples/chapter11_07/src/util/STL/cstdbool | 15 +- examples/chapter11_07/src/util/STL/cstdint | 29 +- examples/chapter11_07/src/util/STL/cstdlib | 24 +- examples/chapter11_07/src/util/STL/cstring | 21 +- examples/chapter11_07/src/util/STL/functional | 18 +- .../src/util/STL/impl/alloc_traits.h | 305 +++ .../util/STL/impl/arm/arm_float_limits.cpp | 69 - .../src/util/STL/impl/avr/avr_atomic.h | 4 +- .../util/STL/impl/avr/avr_float_limits.cpp | 69 - .../impl/avr/avr_hardware_random_device.cpp | 41 + .../src/util/STL/impl/cmath_impl_gamma.cpp | 128 +- .../util/STL/impl/cmath_impl_hyperbolic.cpp | 73 +- .../src/util/STL/impl/ptr_traits.h | 185 ++ .../util/STL/impl/rl78/rl78_float_limits.cpp | 69 - .../src/util/STL/impl/stl_local_constexpr.h | 26 +- .../src/util/STL/impl/stl_local_noexcept.h | 2 + .../src/util/STL/impl/xcmath_impl.h | 27 +- examples/chapter11_07/src/util/STL/iterator | 109 +- examples/chapter11_07/src/util/STL/limits | 1295 ++++++------ examples/chapter11_07/src/util/STL/memory | 111 +- examples/chapter11_07/src/util/STL/random | 1785 +++++++++++++++-- examples/chapter11_07/src/util/STL/ratio | 2 +- examples/chapter11_07/src/util/STL/span | 7 +- examples/chapter11_07/src/util/STL/stdexcept | 110 + examples/chapter11_07/src/util/STL/stdfloat | 35 + examples/chapter11_07/src/util/STL/string | 6 + examples/chapter11_07/src/util/STL/time.h | 4 +- examples/chapter11_07/src/util/STL/tuple | 578 +++--- .../chapter11_07/src/util/STL/type_traits | 319 ++- examples/chapter11_07/src/util/STL/utility | 49 +- examples/chapter11_07/src/util/STL/version | 16 + .../src/util/STL_C++XX_stdfloat/cstdfloat | 12 +- .../src/util/memory/util_factory.h | 74 +- .../util/memory/util_n_slot_array_allocator.h | 195 ++ .../src/util/memory/util_placed_pointer.h | 2 +- .../src/util/memory/util_ring_allocator.h | 60 +- .../src/util/memory/util_static_allocator.h | 4 +- .../memory/util_safety_rom_memory_checksum.h | 9 +- .../src/util/utility/util_alignas.h | 2 +- .../src/util/utility/util_baselexical_cast.h | 173 ++ .../src/util/utility/util_bit_mask.h | 56 +- .../src/util/utility/util_circular_buffer.h | 374 ---- .../src/util/utility/util_communication.h | 98 +- .../src/util/utility/util_countof.h | 42 +- .../src/util/utility/util_display.h | 46 + .../src/util/utility/util_dynamic_array.h | 455 +++-- .../src/util/utility/util_dynamic_bitset.h | 73 +- .../util/utility/util_linear_interpolate.h | 19 +- .../src/util/utility/util_narrow_cast.h | 22 + .../src/util/utility/util_noncopyable.h | 50 +- .../src/util/utility/util_nothing.h | 28 +- .../src/util/utility/util_point.h | 61 +- .../src/util/utility/util_random_pcg32.h | 163 -- .../src/util/utility/util_stopwatch.h | 35 +- .../chapter11_07/src/util/utility/util_swdm.h | 47 +- .../chapter11_07/src/util/utility/util_time.h | 113 +- .../utility/util_two_part_data_manipulation.h | 41 +- .../src/util/utility/util_utype_helper.h | 80 +- .../chapter11_07/target/app/make/app_make.gmk | 310 ++- .../target/app/make/app_rules.gmk | 48 +- .../target/micros/avr/make/avr.ld | 3 +- .../target/micros/avr/make/avr_flags.gmk | 45 +- .../target/micros/avr/startup/crt0.cpp | 2 +- .../micros/avr/startup/crt0_init_ram.cpp | 2 +- .../target/micros/avr/startup/crt1.cpp | 2 +- .../target/micros/avr/startup/int_vect.cpp | 2 +- .../target/micros/avr/make/avr.ld | 2 +- .../target/micros/avr/make/avr_files.gmk | 8 +- .../target/micros/avr/startup/crt0.cpp | 2 +- .../micros/avr/startup/crt0_init_ram.cpp | 2 +- .../target/micros/avr/startup/crt1.cpp | 2 +- .../target/micros/avr/startup/int_vect.cpp | 2 +- ref_app/src/mcal/avr/mcal_cpu.cpp | 2 +- ref_app/src/mcal/avr/mcal_irq.h | 2 +- ref_app/src/mcal/avr/mcal_osc.h | 6 +- ref_app/src/mcal/avr/mcal_port.h | 4 +- ref_app/src/mcal/avr/mcal_reg.h | 15 + 118 files changed, 7285 insertions(+), 3681 deletions(-) create mode 100644 examples/chapter11_07/src/math/checksums/crc/crc32.h create mode 100644 examples/chapter11_07/src/util/STD_LIBC/memory.c delete mode 100644 examples/chapter11_07/src/util/STD_LIBC/memory.cpp create mode 100644 examples/chapter11_07/src/util/STL/cassert create mode 100644 examples/chapter11_07/src/util/STL/cerrno create mode 100644 examples/chapter11_07/src/util/STL/charconv create mode 100644 examples/chapter11_07/src/util/STL/cinttypes create mode 100644 examples/chapter11_07/src/util/STL/ciso646 create mode 100644 examples/chapter11_07/src/util/STL/impl/alloc_traits.h delete mode 100644 examples/chapter11_07/src/util/STL/impl/arm/arm_float_limits.cpp delete mode 100644 examples/chapter11_07/src/util/STL/impl/avr/avr_float_limits.cpp create mode 100644 examples/chapter11_07/src/util/STL/impl/avr/avr_hardware_random_device.cpp create mode 100644 examples/chapter11_07/src/util/STL/impl/ptr_traits.h delete mode 100644 examples/chapter11_07/src/util/STL/impl/rl78/rl78_float_limits.cpp create mode 100644 examples/chapter11_07/src/util/STL/stdexcept create mode 100644 examples/chapter11_07/src/util/STL/stdfloat create mode 100644 examples/chapter11_07/src/util/STL/version create mode 100644 examples/chapter11_07/src/util/memory/util_n_slot_array_allocator.h create mode 100644 examples/chapter11_07/src/util/utility/util_baselexical_cast.h delete mode 100644 examples/chapter11_07/src/util/utility/util_circular_buffer.h create mode 100644 examples/chapter11_07/src/util/utility/util_display.h create mode 100644 examples/chapter11_07/src/util/utility/util_narrow_cast.h delete mode 100644 examples/chapter11_07/src/util/utility/util_random_pcg32.h diff --git a/examples/chapter11_07/chapter11_07.cppproj b/examples/chapter11_07/chapter11_07.cppproj index 54d420823..22aa72a40 100644 --- a/examples/chapter11_07/chapter11_07.cppproj +++ b/examples/chapter11_07/chapter11_07.cppproj @@ -56,57 +56,58 @@ - chapter03_02 + chapter11_07 .elf - -mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega328p" - True - True - True - True - False - - - %24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include - ../src/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 - ../src/os/FreeRTOS/Source/portable/GCC-ATMega328 - ../src/os/FreeRTOS/Source/include - - - True - True - -std=gnu99 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast - - - ../src - ../src/mcal/avr - ../src/util/STL - ../src/os/FreeRTOS/Source/include - ../src/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 - ../src/os/FreeRTOS/Source/portable/GCC-ATMega328 - ../src/util/STL_C++XX_stdfloat - - - Optimize more (-O2) - True - True - -Wextra -gdwarf-2 -fno-use-cxa-atexit -fno-exceptions -finline-functions -finline-limit=64 -std=c++14 -fno-rtti -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs - True - True - True - 0x800 - -Wl,-T../target/micros/avr/make/avr.ld - - - %24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include - - - + -mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega328p" + True + True + True + True + False + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include + ../src/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 + ../src/os/FreeRTOS/Source/portable/GCC-ATMega328 + ../src/os/FreeRTOS/Source/include + + + Optimize more (-O2) + True + True + -std=gnu99 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast + + + ../src + ../src/mcal/avr + ../src/util/STL + ../src/os/FreeRTOS/Source/include + ../src/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 + ../src/os/FreeRTOS/Source/portable/GCC-ATMega328 + ../src/util/STL_C++XX_stdfloat + + + Optimize more (-O2) + True + True + -Wextra -gdwarf-2 -fno-use-cxa-atexit -fno-exceptions -finline-functions -finline-limit=64 -std=c++14 -fno-rtti -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs + True + True + True + 0x800 + -Wl,-T../target/micros/avr/make/avr.ld + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include + + + - chapter03_02 + chapter11_07 .elf @@ -152,7 +153,8 @@ - + + @@ -191,7 +193,7 @@ compile - + compile @@ -371,6 +373,9 @@ compile + + compile + compile @@ -380,16 +385,28 @@ compile - + compile - + compile + + compile + compile - + + compile + + + compile + + + compile + + compile @@ -398,6 +415,9 @@ compile + + compile + compile @@ -407,10 +427,10 @@ compile - + compile - + compile @@ -419,19 +439,28 @@ compile + + compile + compile + + compile + compile - + compile - + compile - + + compile + + compile @@ -440,6 +469,9 @@ compile + + compile + compile @@ -478,12 +510,30 @@ compile + + compile + + + compile + + + compile + compile + + compile + compile + + compile + + + compile + compile @@ -505,6 +555,9 @@ compile + + compile + compile @@ -526,9 +579,21 @@ compile + + compile + compile + + compile + + + compile + + + compile + compile @@ -544,6 +609,9 @@ compile + + compile + compile diff --git a/examples/chapter11_07/chapter11_07.vcxproj b/examples/chapter11_07/chapter11_07.vcxproj index 15400a784..f464b44b3 100644 --- a/examples/chapter11_07/chapter11_07.vcxproj +++ b/examples/chapter11_07/chapter11_07.vcxproj @@ -221,18 +221,23 @@ - + + true true - + + true + true + + true true - + true true @@ -316,6 +321,7 @@ + @@ -323,10 +329,18 @@ true true + + true + true + true true + + true + true + true true @@ -335,25 +349,31 @@ true true + + true + true + true true + - + + - + @@ -363,7 +383,10 @@ true true - + + true + true + true true @@ -376,14 +399,38 @@ true true + + true + true + + + true + true + + + true + true + true true + + true + true + true true + + true + true + + + true + true + true true @@ -412,6 +459,10 @@ true true + + true + true + true true @@ -440,10 +491,26 @@ true true + + true + true + true true + + true + true + + + true + true + + + true + true + true true @@ -464,6 +531,10 @@ true true + + true + true + diff --git a/examples/chapter11_07/chapter11_07.vcxproj.filters b/examples/chapter11_07/chapter11_07.vcxproj.filters index b8164853f..6ba8795bc 100644 --- a/examples/chapter11_07/chapter11_07.vcxproj.filters +++ b/examples/chapter11_07/chapter11_07.vcxproj.filters @@ -40,15 +40,9 @@ {128d0cd4-9202-42ba-bab0-b272686c608a} - - {754304dc-3c88-45b7-91c1-07b6b01cd0e3} - {dfa2f093-24da-4076-a6b5-1c263efdd637} - - {3fb05a5e-c4f3-489c-90bc-1a9385f5730c} - {79de0cd1-30d8-4628-9e4d-29a4ba48c60a} @@ -97,6 +91,15 @@ {63a11b61-9e28-4ba2-bc96-b75109f5c0d9} + + {6f276992-b3e7-4723-846b-c4f334029637} + + + {810b0c10-a30b-4927-b6dd-8b0560723216} + + + {b584eda9-37f6-4508-86cd-73f8a70a246c} + @@ -105,12 +108,6 @@ src\mcal - - src\util\STL\impl\avr - - - src\util\STD_LIBC - src\app\led @@ -177,74 +174,26 @@ src\os\FreeRTOS\Source\portable\GCC-ATMega328 + + src\util\STD_LIBC + + + src\util\STL\impl\avr + + + src\util\STL\impl + + + src\util\STL\impl + src\mcal - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - src\util\STL\impl\avr - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\utility - - - src\util\STL\impl - - - src\util\STL\impl - - - src\util\STL\impl - - - src\util\STL - src\util\STL_C++XX_stdfloat @@ -260,12 +209,6 @@ src\util\memory - - src\math\primes - - - src\util\utility - src\mcal_spi @@ -422,45 +365,135 @@ src\os\FreeRTOS\Source\include\cfg\GCC-ATMega328 + + src\util\memory + + + src\util\STL\impl + + + src\util\STL\impl + + + src\util\STL\impl + + + src\util\STL\impl + + + src\util\STL\impl + + + src\util\STL\impl + + + src\util\STL + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\util\utility + + + src\math\checksums\crc + - + + src\util\STL_C++XX_stdfloat + + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + + src\util\STL + + src\util\STL @@ -469,43 +502,73 @@ src\util\STL + + src\util\STL + src\util\STL src\util\STL - + src\util\STL - + src\util\STL - + + src\util\STL + + + src\util\STL + + + src\util\STL + + + src\util\STL + + + src\util\STL + + + src\util\STL + + src\util\STL src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - + src\util\STL - - src\util\STL_C++XX_stdfloat + + src\util\STL - + + src\util\STL + + + src\util\STL + + + src\util\STL + + src\util\STL diff --git a/examples/chapter11_07/src/app/led/app_led.cpp b/examples/chapter11_07/src/app/led/app_led.cpp index 47a02847c..22ab028ce 100644 --- a/examples/chapter11_07/src/app/led/app_led.cpp +++ b/examples/chapter11_07/src/app/led/app_led.cpp @@ -1,11 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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 #include @@ -30,7 +31,7 @@ void app_led_task_background(void*) { while((!app_led_timer_background.timeout())) { - ; + mcal::cpu::nop(); } app_led_timer_background.start_interval(app_led_timer_type::milliseconds(50U)); @@ -57,6 +58,6 @@ void app_led_task_toggle_led0(void*) mcal::led::led0().toggle(); } - OS_TASK_WAIT_YIELD(OS_TASK_MSEC(70U)); + OS_TASK_WAIT_YIELD(OS_TASK_MSEC(125U)); } } diff --git a/examples/chapter11_07/src/app/led/app_led.h b/examples/chapter11_07/src/app/led/app_led.h index 1eab77357..2dd75bc8d 100644 --- a/examples/chapter11_07/src/app/led/app_led.h +++ b/examples/chapter11_07/src/app/led/app_led.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2020. +// Copyright Christopher Kormanyos 2020 - 2024. // 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) // -#ifndef APP_LED_2020_10_07_H_ - #define APP_LED_2020_10_07_H_ +#ifndef APP_LED_2020_10_07_H + #define APP_LED_2020_10_07_H #if defined(__cplusplus) extern "C" @@ -20,4 +20,4 @@ } #endif -#endif // APP_LED_2020_10_07_H_ +#endif // APP_LED_2020_10_07_H diff --git a/examples/chapter11_07/src/math/checksums/crc/crc32.h b/examples/chapter11_07/src/math/checksums/crc/crc32.h new file mode 100644 index 000000000..4768bfc23 --- /dev/null +++ b/examples/chapter11_07/src/math/checksums/crc/crc32.h @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 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) +// + +#ifndef CRC32_2015_01_26_H_ + #define CRC32_2015_01_26_H_ + + #include + #include + + namespace math { namespace checksums { namespace crc { + + template + std::uint32_t crc32_mpeg2(input_iterator first, + input_iterator last) + { + // Name : CRC-32/MPEG-2 + // Polynomial : 0x04C11DB7 + // Initial value : 0xFFFFFFFF + // Test: '1'...'9' : 0x0376E6E7 + + // ISO/IEC 13818-1:2000 + // Recommendation H.222.0 Annex A + + // CRC32/MPEG2 Table based on nibbles. + constexpr std::array table = + {{ + UINT32_C(0x00000000), UINT32_C(0x04C11DB7), + UINT32_C(0x09823B6E), UINT32_C(0x0D4326D9), + UINT32_C(0x130476DC), UINT32_C(0x17C56B6B), + UINT32_C(0x1A864DB2), UINT32_C(0x1E475005), + UINT32_C(0x2608EDB8), UINT32_C(0x22C9F00F), + UINT32_C(0x2F8AD6D6), UINT32_C(0x2B4BCB61), + UINT32_C(0x350C9B64), UINT32_C(0x31CD86D3), + UINT32_C(0x3C8EA00A), UINT32_C(0x384FBDBD) + }}; + + // Set the initial value and loop through the input data stream. + + std::uint32_t crc = UINT32_C(0xFFFFFFFF); + + for( ; first != last; ++first) + { + const std::uint_fast8_t the_byte = uint_fast8_t((*first) & UINT8_C(0xFF)); + + std::uint_fast8_t index; + + // Perform the CRC32/MPEG2 algorithm. + index = ((std::uint_fast8_t(crc >> 28)) ^ (std::uint_fast8_t(the_byte >> 4))) & UINT8_C(0x0F); + + crc = std::uint32_t(std::uint32_t(crc << 4) & UINT32_C(0xFFFFFFF0)) ^ table[index]; + + index = ((std::uint_fast8_t(crc >> 28)) ^ (std::uint_fast8_t(the_byte))) & UINT8_C(0x0F); + + crc = std::uint32_t(std::uint32_t(crc << 4) & UINT32_C(0xFFFFFFF0)) ^ table[index]; + } + + return crc; + } + + } } } // namespace math::checksums::crc + +#endif // CRC32_2015_01_26_H_ diff --git a/examples/chapter11_07/src/mcal/avr/mcal_cpu.cpp b/examples/chapter11_07/src/mcal/avr/mcal_cpu.cpp index 563fa3ca9..edcd33a85 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_cpu.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_cpu.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -10,7 +10,7 @@ #include #include -void mcal::cpu::init() +auto mcal::cpu::init() -> void { mcal::wdg::init(nullptr); mcal::port::init(nullptr); diff --git a/examples/chapter11_07/src/mcal/avr/mcal_cpu.h b/examples/chapter11_07/src/mcal/avr/mcal_cpu.h index 628cdd28e..04999205f 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_cpu.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_cpu.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_CPU_2009_02_14_H_ - #define MCAL_CPU_2009_02_14_H_ +#ifndef MCAL_CPU_2009_02_14_H + #define MCAL_CPU_2009_02_14_H #include @@ -16,10 +16,10 @@ { void init(); - inline void post_init() { } + inline auto post_init() -> void { } - inline void nop() noexcept { asm volatile("nop"); } + inline auto nop() noexcept -> void { asm volatile("nop"); } } } -#endif // MCAL_CPU_2009_02_14_H_ +#endif // MCAL_CPU_2009_02_14_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_gpt.cpp b/examples/chapter11_07/src/mcal/avr/mcal_gpt.cpp index 93685d46b..e3bf26926 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_gpt.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_gpt.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -11,72 +11,96 @@ namespace { // The one (and only one) system tick. - volatile mcal::gpt::value_type system_tick; + volatile auto mcal_gpt_system_tick = mcal::gpt::value_type { }; - bool& gpt_is_initialized() __attribute__((used, noinline)); + auto gpt_is_initialized() -> bool& __attribute__((used, noinline)); - bool& gpt_is_initialized() + auto gpt_is_initialized() -> bool& { - static bool is_init = bool(); + static auto is_init = bool { }; return is_init; } } extern "C" -void __vector_16() __attribute__((signal, used, externally_visible)); +auto __vector_16(void) -> void __attribute__((signal, used, externally_visible)); -void __vector_16() +auto __vector_16(void) -> void { - // Increment the 32-bit system tick with 0x80, representing 128 microseconds. - const mcal::gpt::value_type new_tick = system_tick + static_cast(0x80U); + // Increment the 32-bit system tick with 0x100, representing 256 [(1/2) us]. + // This is basically the roll-over of the 8-bit timer0 at 2MHz each 128us. - system_tick = new_tick; + const auto new_tick = + static_cast + ( + mcal_gpt_system_tick + static_cast(UINT16_C(0x100)) + ); + + mcal_gpt_system_tick = new_tick; } -void mcal::gpt::init(const config_type*) +auto mcal::gpt::init(const config_type*) -> void { - if(gpt_is_initialized() == false) + if(!gpt_is_initialized()) { // Clear the timer0 overflow flag. - mcal::reg::reg_access_static::reg_set(); + mcal::reg::reg_access_static(UINT8_C(0x01))>::reg_set(); // Enable the timer0 overflow interrupt. - mcal::reg::reg_access_static::reg_set(); + mcal::reg::reg_access_static(UINT8_C(0x01))>::reg_set(); // Set the timer0 clock source to f_osc/8 = 2MHz and begin counting. - mcal::reg::reg_access_static::reg_set(); + mcal::reg::reg_access_static(UINT8_C(0x02))>::reg_set(); // Set the is-initialized indication flag. gpt_is_initialized() = true; } } -mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed() +auto mcal::gpt::secure::get_time_elapsed() -> mcal::gpt::value_type { if(gpt_is_initialized()) { // Return the system tick using a multiple read to ensure data consistency. - typedef std::uint8_t timer_address_type; - typedef std::uint8_t timer_register_type; + using timer_address_type = std::uint8_t; + using timer_register_type = std::uint8_t; // Do the first read of the timer0 counter and the system tick. - const timer_register_type tim0_cnt_1 = mcal::reg::reg_access_static::reg_get(); - const mcal::gpt::value_type sys_tick_1 = system_tick; + const auto t0_cnt_1 = mcal::reg::reg_access_static::reg_get(); + const auto sys_tick_1 = mcal_gpt_system_tick; // Do the second read of the timer0 counter. - const timer_register_type tim0_cnt_2 = mcal::reg::reg_access_static::reg_get(); + const auto t0_cnt_2 = mcal::reg::reg_access_static::reg_get(); - // Perform the consistency check. - const mcal::gpt::value_type consistent_microsecond_tick = - ((tim0_cnt_2 >= tim0_cnt_1) ? mcal::gpt::value_type(sys_tick_1 | std::uint8_t(tim0_cnt_1 >> 1U)) - : mcal::gpt::value_type(system_tick | std::uint8_t(tim0_cnt_2 >> 1U))); + const auto t0_tick_is_consistent = (t0_cnt_2 >= t0_cnt_1); - return consistent_microsecond_tick; + // Perform the consistency check. + const auto consistent_half_microsecond_tick = + static_cast + ( + t0_tick_is_consistent ? static_cast(sys_tick_1 | t0_cnt_1) + : static_cast(mcal_gpt_system_tick | t0_cnt_2) + ); + + // Scale the timer0 tick to 1MHz and perform a rounding correction. + return + static_cast + ( + static_cast + ( + static_cast + ( + static_cast(consistent_half_microsecond_tick) + + static_cast(UINT8_C(1)) + ) + / static_cast(UINT8_C(2)) + ) + ); } else { - return mcal::gpt::value_type(0U); + return static_cast(UINT8_C(0)); } } diff --git a/examples/chapter11_07/src/mcal/avr/mcal_gpt.h b/examples/chapter11_07/src/mcal/avr/mcal_gpt.h index edd0451b6..ff787ed80 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_gpt.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_gpt.h @@ -1,18 +1,16 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_GPT_2011_10_20_H_ - #define MCAL_GPT_2011_10_20_H_ +#ifndef MCAL_GPT_2011_10_20_H + #define MCAL_GPT_2011_10_20_H #include #include - #include - // Forward declaration of the util::timer template class. namespace util { @@ -24,17 +22,17 @@ { namespace gpt { - typedef void config_type; - typedef std::uint32_t value_type; + using config_type = void; + using value_type = std::uint64_t; - void init(const config_type*); + auto init(const config_type*) -> void; struct secure final { private: - static value_type get_time_elapsed(); + static auto get_time_elapsed() -> value_type; - friend std::chrono::high_resolution_clock::time_point std::chrono::high_resolution_clock::now() UTIL_NOEXCEPT; + friend auto std::chrono::high_resolution_clock::now() noexcept -> std::chrono::high_resolution_clock::time_point; template friend class util::timer; @@ -42,4 +40,4 @@ } } -#endif // MCAL_GPT_2011_10_20_H_ +#endif // MCAL_GPT_2011_10_20_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_irq.cpp b/examples/chapter11_07/src/mcal/avr/mcal_irq.cpp index b4d246f27..fec202051 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_irq.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_irq.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -7,7 +7,7 @@ #include -void mcal::irq::init(const config_type*) +auto mcal::irq::init(const config_type*) -> void { mcal::irq::enable_all(); } diff --git a/examples/chapter11_07/src/mcal/avr/mcal_irq.h b/examples/chapter11_07/src/mcal/avr/mcal_irq.h index 6ed65840a..65959f4da 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_irq.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_irq.h @@ -1,24 +1,24 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_IRQ_2010_04_10_H_ - #define MCAL_IRQ_2010_04_10_H_ +#ifndef MCAL_IRQ_2010_04_10_H + #define MCAL_IRQ_2010_04_10_H namespace mcal { namespace irq { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; - inline void enable_all () noexcept { asm volatile("sei"); } - inline void disable_all() noexcept { asm volatile("cli"); } + inline auto enable_all () noexcept -> void { asm volatile("sei"); } + inline auto disable_all() noexcept -> void { asm volatile("cli"); } } } -#endif // MCAL_IRQ_2010_04_10_H_ +#endif // MCAL_IRQ_2010_04_10_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_led.cpp b/examples/chapter11_07/src/mcal/avr/mcal_led.cpp index 726982d7d..1883d5425 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_led.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_led.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -8,7 +8,7 @@ #include #include -mcal::led::led_base& mcal::led::led0() +auto mcal::led::led0() -> mcal::led::led_base& { using led0_port_type = mcal::port::port_pin mcal::led::led_base& { using led1_port_type = mcal::port::port_pin @@ -14,9 +14,9 @@ { namespace led { - led_base& led0(); - led_base& led1(); + auto led0() -> led_base&; + auto led1() -> led_base&; } } -#endif // MCAL_LED_2010_09_14_H_ +#endif // MCAL_LED_2010_09_14_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_memory_progmem.h b/examples/chapter11_07/src/mcal/avr/mcal_memory_progmem.h index e4bc7f0ec..8570aa447 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_memory_progmem.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_memory_progmem.h @@ -1,14 +1,14 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2019 - 2020. +// Copyright Christopher Kormanyos 2019 - 2024. // 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) // -#ifndef MCAL_MEMORY_PROGMEM_2019_08_17_H_ - #define MCAL_MEMORY_PROGMEM_2019_08_17_H_ +#ifndef MCAL_MEMORY_PROGMEM_2019_08_17_H + #define MCAL_MEMORY_PROGMEM_2019_08_17_H - #include + #include #include @@ -59,4 +59,4 @@ } #endif -#endif // MCAL_MEMORY_PROGMEM_2019_08_17_H_ +#endif // MCAL_MEMORY_PROGMEM_2019_08_17_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_osc.cpp b/examples/chapter11_07/src/mcal/avr/mcal_osc.cpp index b720119e4..65f51ae6a 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_osc.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_osc.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -7,6 +7,6 @@ #include -void mcal::osc::init(const config_type*) +auto mcal::osc::init(const config_type*) -> void { } diff --git a/examples/chapter11_07/src/mcal/avr/mcal_osc.h b/examples/chapter11_07/src/mcal/avr/mcal_osc.h index 188e43115..8d344575b 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_osc.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_osc.h @@ -1,21 +1,21 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_OSC_2011_10_20_H_ - #define MCAL_OSC_2011_10_20_H_ +#ifndef MCAL_OSC_2011_10_20_H + #define MCAL_OSC_2011_10_20_H namespace mcal { namespace osc { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; } } -#endif // MCAL_OSC_2011_10_20_H_ +#endif // MCAL_OSC_2011_10_20_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_port.cpp b/examples/chapter11_07/src/mcal/avr/mcal_port.cpp index c5e938a78..c1452f8ad 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_port.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_port.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -7,6 +7,6 @@ #include -void mcal::port::init(const config_type*) +auto mcal::port::init(const config_type*) -> void { } diff --git a/examples/chapter11_07/src/mcal/avr/mcal_port.h b/examples/chapter11_07/src/mcal/avr/mcal_port.h index 9969899c5..cca87d7c5 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_port.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_port.h @@ -1,22 +1,24 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_PORT_2012_06_27_H_ - #define MCAL_PORT_2012_06_27_H_ +#ifndef MCAL_PORT_2012_06_27_H + #define MCAL_PORT_2012_06_27_H #include + #include + namespace mcal { namespace port { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; template void { // Set the port pin's direction to output. // C++: @@ -46,7 +48,7 @@ asm volatile("sbi %[myport],%[mybit]" : : [myport]"I"(pdir_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_direction_input() + static auto set_direction_input() noexcept -> void { // Set the port pin's direction to input. // C++: @@ -57,7 +59,7 @@ asm volatile("cbi %[myport],%[mybit]" : : [myport]"I"(pdir_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_pin_high() + static auto set_pin_high() noexcept -> void { // Set the port output value to high. // C++: @@ -68,7 +70,7 @@ asm volatile("sbi %[myport],%[mybit]" : : [myport]"I"(port_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_pin_low() + static auto set_pin_low() noexcept -> void { // Set the port output value to low. // C++: @@ -79,7 +81,7 @@ asm volatile("cbi %[myport],%[mybit]" : : [myport]"I"(port_address - sfr_offset), [mybit]"I"(bpos_value)); } - static bool read_input_value() + static auto read_input_value() noexcept -> bool { // Read the port input value. return mcal::reg::reg_access_static::bit_get(); } - static void toggle_pin() + static auto toggle_pin() noexcept -> void { // Toggle the port output value. mcal::reg::reg_access_static @@ -17,32 +17,32 @@ constexpr std::uint8_t sfr_offset = 0x20U; // Bit-position values. - constexpr std::uint8_t bval0 = 1U; - constexpr std::uint8_t bval1 = 1U << 1U; - constexpr std::uint8_t bval2 = 1U << 2U; - constexpr std::uint8_t bval3 = 1U << 3U; - constexpr std::uint8_t bval4 = 1U << 4U; - constexpr std::uint8_t bval5 = 1U << 5U; - constexpr std::uint8_t bval6 = 1U << 6U; - constexpr std::uint8_t bval7 = 1U << 7U; + constexpr std::uint8_t bval0 { 1U }; + constexpr std::uint8_t bval1 { 1U << 1U }; + constexpr std::uint8_t bval2 { 1U << 2U }; + constexpr std::uint8_t bval3 { 1U << 3U }; + constexpr std::uint8_t bval4 { 1U << 4U }; + constexpr std::uint8_t bval5 { 1U << 5U }; + constexpr std::uint8_t bval6 { 1U << 6U }; + constexpr std::uint8_t bval7 { 1U << 7U }; // System registers. - constexpr std::uint8_t mcusr = 0x14U + sfr_offset; - constexpr std::uint8_t prr = 0x64U; + constexpr std::uint8_t mcusr { 0x14U + sfr_offset }; + constexpr std::uint8_t prr { 0x64U }; // Port registers. - constexpr std::uint8_t pinb = 0x03U + sfr_offset; - constexpr std::uint8_t ddrb = 0x04U + sfr_offset; - constexpr std::uint8_t portb = 0x05U + sfr_offset; - constexpr std::uint8_t pinc = 0x06U + sfr_offset; - constexpr std::uint8_t ddrc = 0x07U + sfr_offset; - constexpr std::uint8_t portc = 0x08U + sfr_offset; - constexpr std::uint8_t pind = 0x09U + sfr_offset; - constexpr std::uint8_t ddrd = 0x0AU + sfr_offset; - constexpr std::uint8_t portd = 0x0BU + sfr_offset; - constexpr std::uint8_t pine = 0x0CU + sfr_offset; - constexpr std::uint8_t ddre = 0x0DU + sfr_offset; - constexpr std::uint8_t porte = 0x0EU + sfr_offset; + constexpr std::uint8_t pinb { 0x03U + sfr_offset }; + constexpr std::uint8_t ddrb { 0x04U + sfr_offset }; + constexpr std::uint8_t portb { 0x05U + sfr_offset }; + constexpr std::uint8_t pinc { 0x06U + sfr_offset }; + constexpr std::uint8_t ddrc { 0x07U + sfr_offset }; + constexpr std::uint8_t portc { 0x08U + sfr_offset }; + constexpr std::uint8_t pind { 0x09U + sfr_offset }; + constexpr std::uint8_t ddrd { 0x0AU + sfr_offset }; + constexpr std::uint8_t portd { 0x0BU + sfr_offset }; + constexpr std::uint8_t pine { 0x0CU + sfr_offset }; + constexpr std::uint8_t ddre { 0x0DU + sfr_offset }; + constexpr std::uint8_t porte { 0x0EU + sfr_offset }; // Timer register values constexpr std::uint8_t cs10 = 0U; @@ -60,48 +60,48 @@ constexpr std::uint8_t ocie2b = 2U; // Timer registers - constexpr std::uint8_t tifr0 = 0x15U + sfr_offset; - constexpr std::uint8_t tccr0a = 0x24U + sfr_offset; - constexpr std::uint8_t tccr0b = 0x25U + sfr_offset; - constexpr std::uint8_t tcnt0 = 0x26U + sfr_offset; - constexpr std::uint8_t ocr0a = 0x27U + sfr_offset; - constexpr std::uint8_t timsk0 = 0x6EU; + constexpr std::uint8_t tifr0 { 0x15U + sfr_offset }; + constexpr std::uint8_t tccr0a { 0x24U + sfr_offset }; + constexpr std::uint8_t tccr0b { 0x25U + sfr_offset }; + constexpr std::uint8_t tcnt0 { 0x26U + sfr_offset }; + constexpr std::uint8_t ocr0a { 0x27U + sfr_offset }; + constexpr std::uint8_t timsk0 { 0x6EU }; - constexpr std::uint8_t tifr1 = 0x16U + sfr_offset; - constexpr std::uint8_t tccr1a = 0x80U; - constexpr std::uint8_t tccr1b = 0x81U; - constexpr std::uint8_t tcnt1l = 0x84U; - constexpr std::uint8_t tcnt1h = 0x85U; - constexpr std::uint8_t icr1 = 0x86U; // 16-bit register - constexpr std::uint8_t ocr1a = 0x88U; // 16-bit register - constexpr std::uint8_t ocr1b = 0x8AU; // 16-bit register - constexpr std::uint8_t timsk1 = 0x6FU; + constexpr std::uint8_t tifr1 { 0x16U + sfr_offset }; + constexpr std::uint8_t tccr1a { 0x80U }; + constexpr std::uint8_t tccr1b { 0x81U }; + constexpr std::uint8_t tcnt1l { 0x84U }; + constexpr std::uint8_t tcnt1h { 0x85U }; + constexpr std::uint8_t icr1 { 0x86U }; // 16-bit register + constexpr std::uint8_t ocr1a { 0x88U }; // 16-bit register + constexpr std::uint8_t ocr1b { 0x8AU }; // 16-bit register + constexpr std::uint8_t timsk1 { 0x6FU }; - constexpr std::uint8_t tifr2 = 0x17U + sfr_offset; - constexpr std::uint8_t tccr2a = 0xB0U; - constexpr std::uint8_t tccr2b = 0xB1U; - constexpr std::uint8_t tcnt2 = 0xB2U; - constexpr std::uint8_t ocr2a = 0xB3U; - constexpr std::uint8_t timsk2 = 0x70U; + constexpr std::uint8_t tifr2 { 0x17U + sfr_offset }; + constexpr std::uint8_t tccr2a { 0xB0U }; + constexpr std::uint8_t tccr2b { 0xB1U }; + constexpr std::uint8_t tcnt2 { 0xB2U }; + constexpr std::uint8_t ocr2a { 0xB3U }; + constexpr std::uint8_t timsk2 { 0x70U }; // SPI(TM) registers. - constexpr std::uint8_t spcr = 0x2CU + sfr_offset; - constexpr std::uint8_t spsr = 0x2DU + sfr_offset; - constexpr std::uint8_t spdr = 0x2EU + sfr_offset; + constexpr std::uint8_t spcr { 0x2CU + sfr_offset }; + constexpr std::uint8_t spsr { 0x2DU + sfr_offset }; + constexpr std::uint8_t spdr { 0x2EU + sfr_offset }; // Watchdog registers - constexpr std::uint8_t wdtcsr = 0x60U; + constexpr std::uint8_t wdtcsr { 0x60U }; // Eeprom registers - constexpr std::uint8_t eecr = 0x1FU + sfr_offset; - constexpr std::uint8_t eedr = 0x20U + sfr_offset; - constexpr std::uint8_t eear = 0x21U + sfr_offset; - constexpr std::uint8_t eearl = 0x21U + sfr_offset; - constexpr std::uint8_t eearh = 0x22U + sfr_offset; + constexpr std::uint8_t eecr { 0x1FU + sfr_offset }; + constexpr std::uint8_t eedr { 0x20U + sfr_offset }; + constexpr std::uint8_t eear { 0x21U + sfr_offset }; + constexpr std::uint8_t eearl { 0x21U + sfr_offset }; + constexpr std::uint8_t eearh { 0x22U + sfr_offset }; } } #include #include -#endif // MCAL_REG_2010_04_10_H_ +#endif // MCAL_REG_2010_04_10_H diff --git a/examples/chapter11_07/src/mcal/avr/mcal_wdg.cpp b/examples/chapter11_07/src/mcal/avr/mcal_wdg.cpp index 7e7e4b6c8..c25353aeb 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_wdg.cpp +++ b/examples/chapter11_07/src/mcal/avr/mcal_wdg.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -8,12 +8,7 @@ #include #include -// This following function is not used. -// It is, however, kept as an example of *turning off* -// the wdt if wdton is set in the fuse bits. -void mcal_wdg_turn_off_wdt_if_wdton_is_set(); - -void mcal::wdg::init(const config_type*) +auto mcal::wdg::init(const config_type*) -> void { // Read the MCU status register. volatile const std::uint8_t mcu_status_register = @@ -41,38 +36,16 @@ void mcal::wdg::init(const config_type*) std::uint8_t(0x18U)>::reg_set(); // See Chapter 11.9.2, Table 11-2: Watchdog Timer Prescale Select. - // Select WDP3:WDP0 in WDTCSR to binary 0011, resulting in a watchdog - // period of approximately 125ms. + // Select WDP3:WDP0 in WDTCSR to binary 0b0111, resulting + // in a watchdog period of approximately 2s. mcal::reg::reg_access_static::reg_set(); + std::uint8_t(0x08U) | std::uint8_t(0x07U)>::reg_set(); } -void mcal::wdg::secure::trigger() +auto mcal::wdg::secure::trigger() -> void { asm volatile("wdr"); } -void mcal_wdg_turn_off_wdt_if_wdton_is_set() -{ - asm volatile("wdr"); - - // Clear WDRF in the MCU status register. - mcal::reg::reg_access_static::bit_clr(); - - // Set WDCE and WDE. - mcal::reg::reg_access_static::reg_or(); - - // Turn off the WDT. - mcal::reg::reg_access_static::reg_set(); -} diff --git a/examples/chapter11_07/src/mcal/avr/mcal_wdg.h b/examples/chapter11_07/src/mcal/avr/mcal_wdg.h index fae792719..e801c7e80 100644 --- a/examples/chapter11_07/src/mcal/avr/mcal_wdg.h +++ b/examples/chapter11_07/src/mcal/avr/mcal_wdg.h @@ -1,35 +1,41 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef MCAL_WDT_2010_04_10_H_ - #define MCAL_WDT_2010_04_10_H_ +#ifndef MCAL_WDT_2010_04_10_H + #define MCAL_WDT_2010_04_10_H extern "C" void __my_startup() __attribute__((section(".startup"), used, noinline)); - extern "C" void app_led_task_toggle_led0(void* pv); + extern "C" void app_led_task_toggle_led0(void*); - namespace sys { namespace idle { void task_func(); } } + namespace sys { namespace idle { auto task_func() -> void; } } + + namespace util { template class timer; } namespace mcal { namespace wdg { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; struct secure final { private: - static void trigger(); - - friend void ::app_led_task_toggle_led0(void* pv); + friend auto ::sys::idle::task_func() -> void; friend void ::__my_startup(); + friend void ::app_led_task_toggle_led0(void*); + + template + friend class util::timer; + + static auto trigger() -> void; }; } } -#endif // MCAL_WDT_2010_04_10_H_ +#endif // MCAL_WDT_2010_04_10_H diff --git a/examples/chapter11_07/src/mcal/mcal_gcc_cxx_completion.cpp b/examples/chapter11_07/src/mcal/mcal_gcc_cxx_completion.cpp index 1aaa4b8e8..01cf1b167 100644 --- a/examples/chapter11_07/src/mcal/mcal_gcc_cxx_completion.cpp +++ b/examples/chapter11_07/src/mcal/mcal_gcc_cxx_completion.cpp @@ -1,14 +1,16 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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 +#include + +#include +#include // Implement std::chrono::high_resolution_clock::now() // for the standard library's high-resolution clock. diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_base.h b/examples/chapter11_07/src/mcal_led/mcal_led_base.h index f6b23398b..08e6712a2 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_base.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_base.h @@ -1,29 +1,31 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2013 - 2020. +// Copyright Christopher Kormanyos 2013 - 2024. // 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) // -#ifndef MCAL_LED_BASE_2020_04_32_H_ - #define MCAL_LED_BASE_2020_04_32_H_ +#ifndef MCAL_LED_BASE_2020_04_32_H + #define MCAL_LED_BASE_2020_04_32_H #include namespace mcal { namespace led { - class led_base : private util::noncopyable + class led_base : private util::noncopyable // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: - virtual void toggle() = 0; - virtual bool state_is_on() const = 0; - virtual ~led_base() = default; + virtual auto toggle() -> void = 0; + + virtual auto state_is_on() const -> bool = 0; + protected: - led_base() = default; + constexpr led_base() = default; }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_BASE_2020_04_32_H_ +#endif // MCAL_LED_BASE_2020_04_32_H diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_boolean_state_base.h b/examples/chapter11_07/src/mcal_led/mcal_led_boolean_state_base.h index 9277c48cf..d97b83116 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_boolean_state_base.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_boolean_state_base.h @@ -1,37 +1,38 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2020. +// Copyright Christopher Kormanyos 2020 - 2024. // 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) // -#ifndef MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H_ - #define MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H_ +#ifndef MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H + #define MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H #include namespace mcal { namespace led { - class led_boolean_state_base : public mcal::led::led_base + class led_boolean_state_base : public mcal::led::led_base // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: - virtual ~led_boolean_state_base() = default; + ~led_boolean_state_base() override = default; protected: - led_boolean_state_base() : is_on(false) { } + constexpr led_boolean_state_base() = default; - virtual void toggle() + auto toggle() -> void override { // Toggle the LED state. is_on = (!is_on); } - virtual bool state_is_on() const { return is_on; } + auto state_is_on() const -> bool override { return is_on; } private: - bool is_on; + bool is_on { }; }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H_ +#endif // MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_console.h b/examples/chapter11_07/src/mcal_led/mcal_led_console.h index b0804d02a..ab75469b8 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_console.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_console.h @@ -1,44 +1,47 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2013 - 2020. +// Copyright Christopher Kormanyos 2013 - 2024. // 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) // -#ifndef MCAL_LED_CONSOLE_2020_04_23_H_ - #define MCAL_LED_CONSOLE_2020_04_23_H_ +#ifndef MCAL_LED_CONSOLE_2020_04_23_H + #define MCAL_LED_CONSOLE_2020_04_23_H + + #include #include #include - #include - namespace mcal { namespace led { - class led_console final : public mcal::led::led_boolean_state_base + class led_console final : public mcal::led::led_boolean_state_base // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: - explicit led_console(const std::uint_fast8_t i) - : my_index(i) { } + explicit constexpr led_console(const std::uint_fast8_t idx = std::uint_fast8_t { UINT8_C(0) }) + : my_index(idx) { } - virtual ~led_console() = default; + ~led_console() override = default; - private: - const std::uint_fast8_t my_index; - - virtual void toggle() + auto toggle() -> void override { - led_boolean_state_base::toggle(); + using base_class_type = mcal::led::led_boolean_state_base; + + base_class_type::toggle(); - // Print the LED state. + // Print the LED state to the console. std::cout << "LED" - << unsigned(my_index) + << static_cast(my_index) << " is " - << (led_boolean_state_base::state_is_on() ? "on" : "off") + << (base_class_type::state_is_on() ? "on" : "off") << std::endl; } + + private: + const std::uint_fast8_t my_index { }; }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_CONSOLE_2020_04_23_H_ +#endif // MCAL_LED_CONSOLE_2020_04_23_H diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_port.h b/examples/chapter11_07/src/mcal_led/mcal_led_port.h index 3ce88734a..d7446e685 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_port.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_port.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2013 - 2020. +// Copyright Christopher Kormanyos 2013 - 2024. // 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) // -#ifndef MCAL_LED_PORT_2020_04_23_H_ - #define MCAL_LED_PORT_2020_04_23_H_ +#ifndef MCAL_LED_PORT_2020_04_23_H + #define MCAL_LED_PORT_2020_04_23_H #include #include @@ -23,17 +23,19 @@ port_type::set_direction_output(); } - virtual ~led_port() = default; + ~led_port() override = default; - private: - virtual void toggle() + auto toggle() -> void override { - led_boolean_state_base::toggle(); + using base_class_type = led_boolean_state_base; port_type::toggle_pin(); + + base_class_type::toggle(); } }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_PORT_2020_04_23_H_ +#endif // MCAL_LED_PORT_2020_04_23_H diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_port_inverted.h b/examples/chapter11_07/src/mcal_led/mcal_led_port_inverted.h index 28145fac4..47ede3cab 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_port_inverted.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_port_inverted.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2020. +// Copyright Christopher Kormanyos 2020 - 2024. // 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) // -#ifndef MCAL_LED_PORT_INVERTED_2020_08_02_H_ - #define MCAL_LED_PORT_INVERTED_2020_08_02_H_ +#ifndef MCAL_LED_PORT_INVERTED_2020_08_02_H + #define MCAL_LED_PORT_INVERTED_2020_08_02_H #include #include @@ -23,17 +23,19 @@ port_type::set_direction_output(); } - virtual ~led_port_inverted() = default; + ~led_port_inverted() override = default; - private: - virtual void toggle() + auto toggle() -> void override { - led_boolean_state_base::toggle(); + using base_class_type = led_boolean_state_base; port_type::toggle_pin(); + + base_class_type::toggle(); } }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_PORT_INVERTED_2020_08_02_H_ +#endif // MCAL_LED_PORT_INVERTED_2020_08_02_H diff --git a/examples/chapter11_07/src/mcal_led/mcal_led_pwm.h b/examples/chapter11_07/src/mcal_led/mcal_led_pwm.h index 97b1b53df..1778302db 100644 --- a/examples/chapter11_07/src/mcal_led/mcal_led_pwm.h +++ b/examples/chapter11_07/src/mcal_led/mcal_led_pwm.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2013 - 2020. +// Copyright Christopher Kormanyos 2013 - 2024. // 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) // -#ifndef MCAL_LED_PWM_2020_04_23_H_ - #define MCAL_LED_PWM_2020_04_23_H_ +#ifndef MCAL_LED_PWM_2020_04_23_H + #define MCAL_LED_PWM_2020_04_23_H #include #include @@ -16,27 +16,33 @@ class led_pwm : public mcal::led::led_base { public: - led_pwm(mcal::pwm::pwm_base& pwm) : my_pwm(pwm) + explicit led_pwm(mcal::pwm::pwm_base& pwm) : my_pwm(pwm) { - my_pwm.set_duty(0U); + my_pwm.set_duty(static_cast(UINT8_C(0))); } - virtual ~led_pwm() = default; + ~led_pwm() override = default; - virtual bool state_is_on() const { return (my_pwm.get_duty() > 0U); } + auto state_is_on() const -> bool override { return (my_pwm.get_duty() > static_cast(UINT8_C(0))); } - private: - mcal::pwm::pwm_base& my_pwm; - - virtual void toggle() + auto toggle() -> void override { // Toggle the duty cycle. - const std::uint16_t new_duty = ((my_pwm.get_duty() > 0U) ? 0U : 1000U); + const auto new_duty = + static_cast + ( + state_is_on() ? static_cast(UINT8_C(0)) + : static_cast(UINT16_C(1000)) + ); my_pwm.set_duty(new_duty); } + + private: + mcal::pwm::pwm_base& my_pwm; }; - } } // namespace mcal::led + } // namespace led + } // namespace mcal -#endif // MCAL_LED_PWM_2020_04_23_H_ +#endif // MCAL_LED_PWM_2020_04_23_H diff --git a/examples/chapter11_07/src/util/STD_LIBC/memory.c b/examples/chapter11_07/src/util/STD_LIBC/memory.c new file mode 100644 index 000000000..19eeb68b7 --- /dev/null +++ b/examples/chapter11_07/src/util/STD_LIBC/memory.c @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2011 - 2021. +// 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 + +// Implement some memory functions from the standard C library. +// If this file is included in the project, the linker will take these +// functions instead of its own corresponding functions from the C-library. +// The functions in this file *might* potentially save some code and/or +// runtime in the executable. + +void* memset (void* dest, int val, size_t count) __attribute__((used, noinline)); +void* memcpy (void* dest, const void* src, size_t count) __attribute__((used, noinline)); +void* memmove(void* dst, const void* src, size_t n) __attribute__((used, noinline)); + +void* memset(void* dest, int val, size_t count) +{ + unsigned char* puchar_dest = (uint8_t*) dest; + + for(size_t i = 0U; i < count; ++i) + { + puchar_dest[i] = (uint8_t) val; + } + + return dest; +} + +void* memcpy(void* dest, const void* src, size_t count) +{ + unsigned char* puchar_dest = ( uint8_t*) dest; + const unsigned char* puchar_src = (const uint8_t*) src; + + for(size_t i = 0U; i < count; ++i) + { + puchar_dest[i] = puchar_src[i]; + } + + return (void*) puchar_dest; +} + +void* memmove(void* dest, const void* src, size_t n) +{ + uint8_t* from = (uint8_t*) src; + uint8_t* to = (uint8_t*) dest; + + if(from == to || n == 0) + { + return dest; + } + + if(to > from && (ptrdiff_t) (to - from) < (ptrdiff_t) n) + { + // to overlaps with from + // + // + // copy in reverse, to avoid overwriting from + for(ptrdiff_t i = (ptrdiff_t) (n - 1); i >= 0; --i) + { + to[i] = from[i]; + } + + return dest; + } + + if(from > to && (ptrdiff_t) (from - to) < (ptrdiff_t) n) + { + // to overlaps with from + // + // + // copy forwards, to avoid overwriting from */ + for(size_t i = 0U; i < n; ++i) + { + to[i] = from[i]; + } + + return dest; + } + + memcpy(dest, src, n); + + return dest; +} diff --git a/examples/chapter11_07/src/util/STD_LIBC/memory.cpp b/examples/chapter11_07/src/util/STD_LIBC/memory.cpp deleted file mode 100644 index 1519647a4..000000000 --- a/examples/chapter11_07/src/util/STD_LIBC/memory.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2011 - 2015. -// 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 - -// Implement some efficient memory functions from the standard C library. -// If this file is included in the project, the linker will take these -// functions instead of its own corresponding functions from the C-library. -// The functions in this file *might* potentially save some code and/or -// runtime in the executable. - -extern "C" -void* memset(void* dst, int c, size_t n) -{ - // Convert the value c to unsigned char and copy it to the destination n times. - - std::uint8_t* the_dst = reinterpret_cast(dst); - - for( ; n > static_cast(0U); --n) - { - *the_dst = static_cast(c); - ++the_dst; - } - - return dst; -} - -extern "C" -void* memcpy(void* dst, const void* src, size_t n) -{ - std::uint8_t* the_dst = reinterpret_cast< std::uint8_t*>(dst); - const std::uint8_t* the_src = reinterpret_cast(src); - - for( ; n > static_cast(0U); --n) - { - *the_dst = *the_src; - ++the_dst; - ++the_src; - } - - return dst; -} - -extern "C" -void* memmove(void* dst, const void* src, size_t n) -{ - // The function memmove *does* work properly even when its operands overlap. - - std::uint8_t* the_dst = static_cast< std::uint8_t*>(dst); - const std::uint8_t* the_src = static_cast(src); - - // Check for a range overlap. - if((the_src < the_dst) && (the_dst < (the_src + n))) - { - the_dst += n; - the_src += n; - - for( ; n > static_cast(0U); --n) - { - // Perform a backwards copy. - --the_dst; - --the_src; - *the_dst = *the_src; - } - } - else - { - for( ; n > static_cast(0U); --n) - { - // Perform a forwards copy. - *the_dst = *the_src; - ++the_dst; - ++the_src; - } - } - - return dst; -} diff --git a/examples/chapter11_07/src/util/STL/algorithm b/examples/chapter11_07/src/util/STL/algorithm index 6d6915226..db60841b7 100644 --- a/examples/chapter11_07/src/util/STL/algorithm +++ b/examples/chapter11_07/src/util/STL/algorithm @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -8,6 +8,7 @@ #ifndef ALGORITHM_2010_02_23_ #define ALGORITHM_2010_02_23_ + #include #include #include #include @@ -18,25 +19,31 @@ namespace std { + // Forward declaration. + template + STL_LOCAL_CONSTEXPR_ALGORITHMS void iter_swap(input_iterator1 left, + input_iterator2 right); + template - const value_type& (min)(const value_type& a, - const value_type& b) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (min)(value_type a, + value_type b) { return ((a < b) ? a : b); } template - const value_type& (min)(const value_type& a, - const value_type& b, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (min)(value_type a, + value_type b, + binary_function_type binary_function) { return (binary_function(b, a) ? b : a); } template - forward_iterator min_element(forward_iterator first, - forward_iterator last) + STL_LOCAL_CONSTEXPR_ALGORITHMS forward_iterator min_element(forward_iterator first, + forward_iterator last) { forward_iterator minimum_value = first; @@ -58,9 +65,9 @@ template - forward_iterator min_element(forward_iterator first, - forward_iterator last, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS forward_iterator min_element(forward_iterator first, + forward_iterator last, + binary_function_type binary_function) { forward_iterator minimum_value = first; @@ -81,15 +88,15 @@ } template - value_type (min)(std::initializer_list my_initializer_list) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (min)(std::initializer_list my_initializer_list) { return *std::min_element(my_initializer_list.begin(), my_initializer_list.end()); } template - value_type (min)(std::initializer_list my_initializer_list, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (min)(std::initializer_list my_initializer_list, + binary_function_type binary_function) { return *std::min_element(my_initializer_list.begin(), my_initializer_list.end(), @@ -97,23 +104,23 @@ } template - const value_type& (max)(const value_type& a, - const value_type& b) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (max)(value_type a, + value_type b) { return ((a > b) ? a : b); } template - const value_type& (max)(const value_type& a, - const value_type& b, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (max)(value_type a, + value_type b, + binary_function_type binary_function) { return (binary_function(a, b) ? a : b); } template - forward_iterator max_element(forward_iterator first, forward_iterator last) + STL_LOCAL_CONSTEXPR_ALGORITHMS forward_iterator max_element(forward_iterator first, forward_iterator last) { forward_iterator maximum_value = first; @@ -135,9 +142,9 @@ template - forward_iterator max_element(forward_iterator first, - forward_iterator last, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS forward_iterator max_element(forward_iterator first, + forward_iterator last, + binary_function_type binary_function) { forward_iterator maximum_value = first; @@ -158,15 +165,15 @@ } template - value_type (max)(std::initializer_list my_initializer_list) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (max)(std::initializer_list my_initializer_list) { return *std::max_element(my_initializer_list.begin(), my_initializer_list.end()); } template - value_type (max)(std::initializer_list my_initializer_list, - binary_function_type binary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS value_type (max)(std::initializer_list my_initializer_list, + binary_function_type binary_function) { return *std::max_element(my_initializer_list.begin(), my_initializer_list.end(), @@ -220,13 +227,15 @@ template - output_iterator copy(input_iterator first, - input_iterator last, - output_iterator result) + STL_LOCAL_CONSTEXPR_ALGORITHMS output_iterator copy(input_iterator first, + input_iterator last, + output_iterator result) { for( ; first != last; ++result, ++first) { - *result = *first; + using result_value_type = typename std::iterator_traits::value_type; + + *result = result_value_type(*first); } return result; @@ -234,16 +243,18 @@ template - bidirectional_output_iterator2 copy_backward(bidirectional_input__iterator1 first1, - bidirectional_input__iterator1 last1, - bidirectional_output_iterator2 last2) + STL_LOCAL_CONSTEXPR_ALGORITHMS bidirectional_output_iterator2 copy_backward(bidirectional_input__iterator1 first1, + bidirectional_input__iterator1 last1, + bidirectional_output_iterator2 last2) { while (first1 != last1) { + using out2_value_type = typename std::iterator_traits::value_type; + --last1; --last2; - *last2 = *last1; + *last2 = out2_value_type(*last1); } return last2; @@ -261,7 +272,9 @@ { if(unary_function(*first)) { - *result = *first; + using output_value_type = typename std::iterator_traits::value_type; + + *result = output_value_type(*first); ++result; } @@ -274,22 +287,24 @@ template - void fill(forward_iterator first, - forward_iterator last, - const value_type& value) + STL_LOCAL_CONSTEXPR_ALGORITHMS void fill(forward_iterator first, + forward_iterator last, + const value_type& value) { for( ; first != last; ++first) { - *first = value; + using forward_value_type = typename std::iterator_traits::value_type; + + *first = forward_value_type(value); } } template - output_iterator fill_n(output_iterator first, - size_type count, - const value_type& value) + STL_LOCAL_CONSTEXPR_ALGORITHMS output_iterator fill_n(output_iterator first, + size_type count, + const value_type& value) { const output_iterator last(first + count); @@ -306,7 +321,9 @@ { while(first != last) { - *first = generator(); + using forward_value_type = typename std::iterator_traits::value_type; + + *first = forward_value_type(generator()); ++first; } @@ -321,7 +338,9 @@ { for(size_type i = size_type(0); i < count; ++i) { - *first = generator(); + using output_value_type = typename std::iterator_traits::value_type; + + *first = output_value_type(generator()); ++first; } @@ -330,24 +349,11 @@ } template - void reverse(bidirectional_iterator first, bidirectional_iterator last) + STL_LOCAL_CONSTEXPR_ALGORITHMS void reverse(bidirectional_iterator first, bidirectional_iterator last) { - if(first != last) + while((first != last) && (first != --last)) { - --last; - - while(first != last) - { - typedef typename std::iterator_traits::value_type value_type; - - const value_type tmp(*first); - - *first = *last; - *last = tmp; - - ++first; - --last; - } + std::iter_swap(first++, last); } } @@ -361,7 +367,9 @@ { for( ; first != last; ++first, ++result) { - *result = unary_function(*first); + using output_value_type = typename std::iterator_traits::value_type; + + *result = output_value_type(unary_function(*first)); } return result; @@ -379,7 +387,9 @@ { for( ; first1 != last1; ++first1, ++first2, ++result) { - *result = binary_function(*first1, *first2); + using output_value_type = typename std::iterator_traits::value_type; + + *result = output_value_type(binary_function(*first1, *first2)); } return result; @@ -415,7 +425,7 @@ { while(first1 != last1) { - if(binary_function(*first1, *first2) == false) + if(!binary_function(*first1, *first2)) { break; } @@ -429,9 +439,9 @@ template - bool all_of(iterator_type first, - iterator_type last, - unary_function_type unary_function) + STL_LOCAL_CONSTEXPR_ALGORITHMS bool all_of(iterator_type first, + iterator_type last, + unary_function_type unary_function) { while((first != last) && unary_function(*first)) { @@ -447,7 +457,7 @@ iterator_type last, unary_function_type unary_function) { - while((first != last) && (unary_function(*first) == false)) + while((first != last) && (!unary_function(*first))) { ++first; } @@ -461,7 +471,7 @@ iterator_type last, unary_function_type unary_function) { - while((first != last) && (unary_function(*first) == false)) + while((first != last) && (!unary_function(*first))) { ++first; } @@ -552,6 +562,19 @@ return count_value; } + template + STL_LOCAL_CONSTEXPR_ALGORITHMS std::pair mismatch(InputIt1 first1, + InputIt1 last1, + InputIt2 first2) + { + while(first1 != last1 && *first1 == *first2) + { + ++first1, ++first2; + } + + return std::make_pair(first1, first2); + } + template typename std::iterator_traits::difference_type @@ -746,8 +769,8 @@ } template - void swap(swap_type& left, - swap_type& right) + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(swap_type& left, + swap_type& right) { if(&left != &right) { @@ -758,10 +781,20 @@ } } + template + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(swap_type&& left, + swap_type&& right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } + template - void iter_swap(input_iterator1 left, - input_iterator2 right) + STL_LOCAL_CONSTEXPR_ALGORITHMS void iter_swap(input_iterator1 left, + input_iterator2 right) { typedef typename std::iterator_traits::value_type value_left_type; typedef typename std::iterator_traits::value_type value_right_type; @@ -774,9 +807,9 @@ template - input_iterator2 swap_ranges(input_iterator1 first1, - input_iterator1 last1, - input_iterator2 first2) + STL_LOCAL_CONSTEXPR_ALGORITHMS input_iterator2 swap_ranges(input_iterator1 first1, + input_iterator1 last1, + input_iterator2 first2) { while(first1 != last1) { @@ -791,8 +824,8 @@ template - void swap(value_type(&left) [N], - value_type(&right)[N]) + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(value_type(&left) [N], + value_type(&right)[N]) { swap_ranges(&left[0U], &left[N], &right[0U]); } @@ -805,7 +838,7 @@ { for( ; ; ++first) { - for( ; (first != last) && (unary_function(*first) == true); ++first) + for( ; (first != last) && unary_function(*first); ++first) { ; } @@ -815,7 +848,7 @@ break; } - for( ; (first != --last) && (unary_function(*last) == false); ) + for( ; (first != --last) && (!unary_function(*last)); ) { ; } diff --git a/examples/chapter11_07/src/util/STL/array b/examples/chapter11_07/src/util/STL/array index f3798d9db..334327a5f 100644 --- a/examples/chapter11_07/src/util/STL/array +++ b/examples/chapter11_07/src/util/STL/array @@ -8,41 +8,41 @@ #ifndef ARRAY_2010_02_23_ #define ARRAY_2010_02_23_ + #include + #include #include #include #include - #include - // Implement most of std::array for compilers that do not yet support it. // See ISO/IEC 14882:2011 Chapter 23.3.2. namespace std { - template + template class array { public: // Standard container-local type definitions. - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; value_type elems[N]; static STL_LOCAL_CONSTEXPR size_type static_size = N; - iterator begin() { return elems; } - iterator end () { return elems + N; } + STL_LOCAL_CONSTEXPR iterator begin() { return elems; } + STL_LOCAL_CONSTEXPR iterator end () { return elems + N; } STL_LOCAL_CONSTEXPR const_iterator begin() const { return elems; } STL_LOCAL_CONSTEXPR const_iterator end () const { return elems + N; } @@ -50,8 +50,8 @@ STL_LOCAL_CONSTEXPR const_iterator cbegin() const { return elems; } STL_LOCAL_CONSTEXPR const_iterator cend () const { return elems + N; } - reverse_iterator rbegin() { return reverse_iterator(elems + N); } - reverse_iterator rend () { return reverse_iterator(elems); } + STL_LOCAL_CONSTEXPR reverse_iterator rbegin() { return reverse_iterator(elems + N); } + STL_LOCAL_CONSTEXPR reverse_iterator rend () { return reverse_iterator(elems); } STL_LOCAL_CONSTEXPR const_reverse_iterator rbegin() const { return const_reverse_iterator(elems + N); } STL_LOCAL_CONSTEXPR const_reverse_iterator rend () const { return const_reverse_iterator(elems); } @@ -59,16 +59,16 @@ STL_LOCAL_CONSTEXPR const_reverse_iterator crbegin() const { return const_reverse_iterator(elems + N); } STL_LOCAL_CONSTEXPR const_reverse_iterator crend () const { return const_reverse_iterator(elems); } - reference operator[](const size_type i) { return elems[i]; } + STL_LOCAL_CONSTEXPR reference operator[](const size_type i) { return elems[i]; } STL_LOCAL_CONSTEXPR const_reference operator[](const size_type i) const { return elems[i]; } - reference at(const size_type i) { return elems[i]; } + STL_LOCAL_CONSTEXPR reference at(const size_type i) { return elems[i]; } STL_LOCAL_CONSTEXPR const_reference at(const size_type i) const { return elems[i]; } - reference front() { return elems[0U]; } + STL_LOCAL_CONSTEXPR reference front() { return elems[0U]; } STL_LOCAL_CONSTEXPR const_reference front() const { return elems[0U]; } - reference back() { return elems[N - 1U]; } + STL_LOCAL_CONSTEXPR reference back() { return elems[N - 1U]; } STL_LOCAL_CONSTEXPR const_reference back() const { return elems[N - 1U]; } static STL_LOCAL_CONSTEXPR size_type size() { return N; } @@ -76,36 +76,37 @@ static STL_LOCAL_CONSTEXPR size_type max_size() { return N; } template - void swap(array& y) + STL_LOCAL_CONSTEXPR void swap(array& y) { std::swap_ranges(begin(), end(), y.begin()); } STL_LOCAL_CONSTEXPR const_pointer data() const { return elems; } - pointer data() { return elems; } + STL_LOCAL_CONSTEXPR pointer data() { return elems; } pointer c_array() { return elems; } template - array& operator=(const array& y) + STL_LOCAL_CONSTEXPR array& operator=(const array& y) { std::copy(y.begin(), y.end(), begin()); + return *this; } - void assign(const value_type& value) + STL_LOCAL_CONSTEXPR void assign(const value_type& value) { std::fill_n(elems, N, value); } - void fill(const value_type& value) + STL_LOCAL_CONSTEXPR void fill(const value_type& value) { std::fill_n(elems, N, value); } }; template - bool operator==(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator==(const array& left, const array& right) { return std::equal(left.begin(), left.end(), right.begin()); } @@ -120,31 +121,31 @@ } template - bool operator!=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator!=(const array& left, const array& right) { - return ((left == right) == false); + return (!(left == right)); } template - bool operator>(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator>(const array& left, const array& right) { return (right < left); } template - bool operator>=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator>=(const array& left, const array& right) { - return ((left < right) == false); + return (!(left < right)); } template - bool operator<=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator<=(const array& left, const array& right) { - return ((right < left) == false); + return (!(right < left)); } template - void swap(array& x, array& y) + STL_LOCAL_CONSTEXPR void swap(array& x, array& y) { swap_ranges(x.begin(), x.end(), y.begin()); } diff --git a/examples/chapter11_07/src/util/STL/cassert b/examples/chapter11_07/src/util/STL/cassert new file mode 100644 index 000000000..a31576237 --- /dev/null +++ b/examples/chapter11_07/src/util/STL/cassert @@ -0,0 +1,13 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021 - 2022. +// 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) +// + +#ifndef CASSERT_2021_10_21_ + #define CASSERT_2021_10_21_ + + #include + +#endif // CASSERT_2021_10_21_ diff --git a/examples/chapter11_07/src/util/STL/cerrno b/examples/chapter11_07/src/util/STL/cerrno new file mode 100644 index 000000000..a20898ca3 --- /dev/null +++ b/examples/chapter11_07/src/util/STL/cerrno @@ -0,0 +1,13 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021 - 2022. +// 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) +// + +#ifndef CERRNO_2021_10_21_ + #define CERRNO_2021_10_21_ + + #include + +#endif // CERRNO_2021_10_21_ diff --git a/examples/chapter11_07/src/util/STL/charconv b/examples/chapter11_07/src/util/STL/charconv new file mode 100644 index 000000000..1cb80c4ec --- /dev/null +++ b/examples/chapter11_07/src/util/STL/charconv @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021 - 2024. +// 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) +// + +#ifndef CHARCONV_2021_04_12_ + #define CHARCONV_2021_04_12_ + + // Implement some of for compilers that do not yet support it. + // At the moment, this contains nothing more than the implementation + // of the struct std::to_chars_result. + + #include + + namespace std + { + enum errc + { + my_unknown_errc = 0, + value_too_large = 1, + }; + } + + namespace std + { + struct to_chars_result + { + to_chars_result() : ptr(nullptr), + ec (my_unknown_errc) { } + char* ptr; + errc ec; + friend bool operator==(const to_chars_result&, const to_chars_result&) = default; + }; + + //to_chars_result to_chars(char* first, char* last, + // /* see description */ value, int base = 10); + + to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; + + inline to_chars_result to_chars(char* first, char* last, float value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, long double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + } + +#endif // CHARCONV_2021_04_12_ diff --git a/examples/chapter11_07/src/util/STL/chrono b/examples/chapter11_07/src/util/STL/chrono index 0e7154ef8..0b047620a 100644 --- a/examples/chapter11_07/src/util/STL/chrono +++ b/examples/chapter11_07/src/util/STL/chrono @@ -1,5 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2011 - 2024. +// 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) +// + /////////////////////////////////////////////////////////////////////////////// -/// \author (c) Marco Paland (info@paland.com) +/// \author (c) Marco Paland (info (AT) paland.com) /// 2011-2012, PALANDesign Hannover, Germany /// /// \license LGPLv3 @@ -568,7 +575,7 @@ static const bool is_steady = false; // !!! PLATFORM AND OS SPECIFIC IMPLEMENTATION !!! - static time_point now() STL_LOCAL_NOEXCEPT; + static time_point now() noexcept; }; @@ -598,7 +605,7 @@ static const bool is_steady = true; // !!! PLATFORM AND OS SPECIFIC IMPLEMENTATION !!! - static time_point now() STL_LOCAL_NOEXCEPT; + static time_point now() noexcept; }; diff --git a/examples/chapter11_07/src/util/STL/cinttypes b/examples/chapter11_07/src/util/STL/cinttypes new file mode 100644 index 000000000..2c06e0981 --- /dev/null +++ b/examples/chapter11_07/src/util/STL/cinttypes @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021. +// 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) +// + +#ifndef CINTTYPES_2021_10_19_ + #define CINTTYPES_2021_10_19_ + + #include + #include + + namespace std + { + struct imaxdiv_t { std::intmax_t quot; std::intmax_t rem; }; + + inline std::intmax_t imaxabs(std::intmax_t n) { return ((n < 0) ? -n : n); } + + inline std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) { const std::imaxdiv_t result = { x / y, x % y }; return result; } + } + +#endif // CINTTYPES_2021_10_19_ diff --git a/examples/chapter11_07/src/util/STL/ciso646 b/examples/chapter11_07/src/util/STL/ciso646 new file mode 100644 index 000000000..9d7087bec --- /dev/null +++ b/examples/chapter11_07/src/util/STL/ciso646 @@ -0,0 +1,15 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2023. +// 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) +// + +#ifndef CISO646_2023_08_15 + #define CISO646_2023_08_15 + + // Implement some of for compilers that do not yet support it. + + #include + +#endif // CISO646_2023_08_15 diff --git a/examples/chapter11_07/src/util/STL/cmath b/examples/chapter11_07/src/util/STL/cmath index b8ea9c420..2945c01d6 100644 --- a/examples/chapter11_07/src/util/STL/cmath +++ b/examples/chapter11_07/src/util/STL/cmath @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -8,246 +8,678 @@ #ifndef CMATH_2010_02_23_ #define CMATH_2010_02_23_ - // Implement most of for compilers that do not yet support it. + #include - #include - - #if defined(__GNUC__) - - namespace std - { - #if defined(__AVR__) - #define __BUILTIN_FABSF __builtin_fabs - #define __BUILTIN_FMODF __builtin_fmod - #define __BUILTIN_MODFF __builtin_modff - #define __BUILTIN_FLOORF __builtin_floor - #define __BUILTIN_CEILF __builtin_ceil - #define __BUILTIN_FREXPF __builtin_frexp - #define __BUILTIN_LDEXPF __builtin_ldexp - #define __BUILTIN_SQRTF __builtin_sqrt - #define __BUILTIN_SINF __builtin_sin - #define __BUILTIN_COSF __builtin_cos - #define __BUILTIN_TANF __builtin_tan - #define __BUILTIN_ASINF __builtin_asin - #define __BUILTIN_ACOSF __builtin_acos - #define __BUILTIN_ATANF __builtin_atan - #define __BUILTIN_ATAN2F __builtin_atan2 - #define __BUILTIN_EXPF __builtin_exp - #define __BUILTIN_POWF __builtin_pow - #define __BUILTIN_LOGF __builtin_log - #define __BUILTIN_LOG10F __builtin_log10 - #define __BUILTIN_SINHF __builtin_sinh - #define __BUILTIN_COSHF __builtin_cosh - #define __BUILTIN_TANHF __builtin_tanh - #else - #define __BUILTIN_FABSF __builtin_fabsf - #define __BUILTIN_FMODF __builtin_fmodf - #define __BUILTIN_MODFF __builtin_modff - #define __BUILTIN_FLOORF __builtin_floorf - #define __BUILTIN_CEILF __builtin_ceilf - #define __BUILTIN_FREXPF __builtin_frexpf - #define __BUILTIN_LDEXPF __builtin_ldexpf - #define __BUILTIN_SQRTF __builtin_sqrtf - #define __BUILTIN_SINF __builtin_sinf - #define __BUILTIN_COSF __builtin_cosf - #define __BUILTIN_TANF __builtin_tanf - #define __BUILTIN_ASINF __builtin_asinf - #define __BUILTIN_ACOSF __builtin_acosf - #define __BUILTIN_ATANF __builtin_atanf - #define __BUILTIN_ATAN2F __builtin_atan2f - #define __BUILTIN_EXPF __builtin_expf - #define __BUILTIN_POWF __builtin_powf - #define __BUILTIN_LOGF __builtin_logf - #define __BUILTIN_LOG10F __builtin_log10f - #define __BUILTIN_SINHF __builtin_sinhf - #define __BUILTIN_COSHF __builtin_coshf - #define __BUILTIN_TANHF __builtin_tanhf - #endif // __AVR__ or not __AVR__ stuff - - #define __BUILTIN_FABS __builtin_fabs - #define __BUILTIN_FMOD __builtin_fmod - #define __BUILTIN_MODF __builtin_modf - #define __BUILTIN_FLOOR __builtin_floor - #define __BUILTIN_CEIL __builtin_ceil - #define __BUILTIN_FREXP __builtin_frexp - #define __BUILTIN_LDEXP __builtin_ldexp - #define __BUILTIN_SQRT __builtin_sqrt - #define __BUILTIN_SIN __builtin_sin - #define __BUILTIN_COS __builtin_cos - #define __BUILTIN_TAN __builtin_tan - #define __BUILTIN_ASIN __builtin_asin - #define __BUILTIN_ACOS __builtin_acos - #define __BUILTIN_ATAN __builtin_atan - #define __BUILTIN_ATAN2 __builtin_atan2 - #define __BUILTIN_EXP __builtin_exp - #define __BUILTIN_POW __builtin_pow - #define __BUILTIN_LOG __builtin_log - #define __BUILTIN_LOG10 __builtin_log10 - #define __BUILTIN_SINH __builtin_sinh - #define __BUILTIN_COSH __builtin_cosh - #define __BUILTIN_TANH __builtin_tanh - - #define __BUILTIN_FABSL __builtin_fabsl - #define __BUILTIN_FMODL __builtin_fmodl - #define __BUILTIN_MODFL __builtin_modfl - #define __BUILTIN_FLOORL __builtin_floorl - #define __BUILTIN_CEILL __builtin_ceill - #define __BUILTIN_FREXPL __builtin_frexpl - #define __BUILTIN_LDEXPL __builtin_ldexpl - #define __BUILTIN_SQRTL __builtin_sqrtl - #define __BUILTIN_SINL __builtin_sinl - #define __BUILTIN_COSL __builtin_cosl - #define __BUILTIN_TANL __builtin_tanl - #define __BUILTIN_ASINL __builtin_asinl - #define __BUILTIN_ACOSL __builtin_acosl - #define __BUILTIN_ATANL __builtin_atanl - #define __BUILTIN_ATAN2L __builtin_atan2l - #define __BUILTIN_EXPL __builtin_expl - #define __BUILTIN_POWL __builtin_powl - #define __BUILTIN_LOGL __builtin_logl - #define __BUILTIN_LOG10L __builtin_log10l - #define __BUILTIN_SINHL __builtin_sinhl - #define __BUILTIN_COSHL __builtin_coshl - #define __BUILTIN_TANHL __builtin_tanhl - - inline float abs (float x) { return __BUILTIN_FABSF (x); } - inline double abs (double x) { return __builtin_fabs (x); } - inline long double abs (long double x) { return __BUILTIN_FABSL (x); } - - inline float fabs (float x) { return __BUILTIN_FABSF (x); } - inline double fabs (double x) { return __BUILTIN_FABS (x); } - inline long double fabs (long double x) { return __BUILTIN_FABSL (x); } - - inline float fmod (float x, float y) { return __BUILTIN_FMODF (x, y); } - inline double fmod (double x, double y) { return __BUILTIN_FMOD (x, y); } - inline long double fmod (long double x, long double y) { return __BUILTIN_FMODL (x, y); } - - inline float modf (float x, float* p) { return __BUILTIN_MODFF (x, p); } - inline double modf (double x, double* p) { return __BUILTIN_MODF (x, p); } - inline long double modf (long double x, long double* p) { return __BUILTIN_MODFL (x, p); } - - inline float floor(float x) { return __BUILTIN_FLOORF(x); } - inline double floor(double x) { return __BUILTIN_FLOOR (x); } - inline long double floor(long double x) { return __BUILTIN_FLOORL(x); } - - inline float ceil (float x) { return __BUILTIN_CEILF (x); } - inline double ceil (double x) { return __BUILTIN_CEIL (x); } - inline long double ceil (long double x) { return __BUILTIN_CEILL (x); } - - inline float frexp(float x, int* p) { return __BUILTIN_FREXPF(x, p); } - inline double frexp(double x, int* p) { return __BUILTIN_FREXP (x, p); } - inline long double frexp(long double x, int* p) { return __BUILTIN_FREXPL(x, p); } - - inline float ldexp(float x, int p) { return __BUILTIN_LDEXPF(x, p); } - inline double ldexp(double x, int p) { return __BUILTIN_LDEXP (x, p); } - inline long double ldexp(long double x, int p) { return __BUILTIN_LDEXPL(x, p); } - - inline float sqrt (float x) { return __BUILTIN_SQRTF (x); } - inline double sqrt (double x) { return __BUILTIN_SQRT (x); } - inline long double sqrt (long double x) { return __BUILTIN_SQRTL (x); } - - inline float sin (float x) { return __BUILTIN_SINF (x); } - inline double sin (double x) { return __BUILTIN_SIN (x); } - inline long double sin (long double x) { return __BUILTIN_SINL (x); } - - inline float cos (float x) { return __BUILTIN_COSF (x); } - inline double cos (double x) { return __BUILTIN_COS (x); } - inline long double cos (long double x) { return __BUILTIN_COSL (x); } - - inline float tan (float x) { return __BUILTIN_TANF (x); } - inline double tan (double x) { return __BUILTIN_TAN (x); } - inline long double tan (long double x) { return __BUILTIN_TANL (x); } - - inline float asin (float x) { return __BUILTIN_ASINF (x); } - inline double asin (double x) { return __BUILTIN_ASIN (x); } - inline long double asin (long double x) { return __BUILTIN_ASINL (x); } - - inline float acos (float x) { return __BUILTIN_ACOSF (x); } - inline double acos (double x) { return __BUILTIN_ACOS (x); } - inline long double acos (long double x) { return __BUILTIN_ACOSL (x); } - - inline float atan (float x) { return __BUILTIN_ATANF (x); } - inline double atan (double x) { return __BUILTIN_ATAN (x); } - inline long double atan (long double x) { return __BUILTIN_ATANL (x); } - - inline float atan2(float y, float x) { return __BUILTIN_ATAN2F(y, x); } - inline double atan2(double y, double x) { return __BUILTIN_ATAN2 (y, x); } - inline long double atan2(long double y, long double x) { return __BUILTIN_ATAN2L(y, x); } - - inline float exp (float x) { return __BUILTIN_EXPF (x); } - inline double exp (double x) { return __BUILTIN_EXPF (x); } - inline long double exp (long double x) { return __BUILTIN_EXPL (x); } - - inline float pow (float x, float a) { return __BUILTIN_POWF (x, a); } - inline double pow (double x, double a) { return __BUILTIN_POW (x, a); } - inline long double pow (long double x, long double a) { return __BUILTIN_POWL (x, a); } - - inline float log (float x) { return __BUILTIN_LOGF (x); } - inline double log (double x) { return __BUILTIN_LOG (x); } - inline long double log (long double x) { return __BUILTIN_LOGL (x); } - - inline float log10(float x) { return __BUILTIN_LOG10F(x); } - inline double log10(double x) { return __BUILTIN_LOG10 (x); } - inline long double log10(long double x) { return __BUILTIN_LOG10L(x); } - - inline float sinh (float x) { return __BUILTIN_SINHF (x); } - inline double sinh (double x) { return __BUILTIN_SINH (x); } - inline long double sinh (long double x) { return __BUILTIN_SINHL (x); } - - inline float cosh (float x) { return __BUILTIN_COSHF (x); } - inline double cosh (double x) { return __BUILTIN_COSH (x); } - inline long double cosh (long double x) { return __BUILTIN_COSHL (x); } - - inline float tanh (float x) { return __BUILTIN_TANHF (x); } - inline double tanh (double x) { return __BUILTIN_TANH (x); } - inline long double tanh (long double x) { return __BUILTIN_TANHL (x); } - } // namespace std + // Implement most of for compilers that do not yet support it. + #if defined(__GNUC__) && defined(__AVR__) + #include + + #if !defined(_HUGE_ENUF) + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow + #endif + + #if !defined(INFINITY) + #define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) + #endif + + #if !defined(HUGE_VAL) + #define HUGE_VAL ((double)INFINITY) + #endif + + #if !defined(HUGE_VALF) + #define HUGE_VALF ((float)INFINITY) + #endif + + #if !defined(HUGE_VALL) + #define HUGE_VALL ((long double)INFINITY) + #endif + + #if !defined(NAN) + #define NAN (-(float)(INFINITY * 0.0F)) + #endif + + #define _DENORM (-2) + #define _FINITE (-1) + #define _INFCODE 1 + #define _NANCODE 2 + + #define FP_INFINITE _INFCODE + #define FP_NAN _NANCODE + #define FP_NORMAL _FINITE + #define FP_SUBNORMAL _DENORM + #define FP_ZERO 0 + + #define _C2 1 // 0 if not 2's complement + #define FP_ILOGB0 (-0x7fffffff - _C2) + #define FP_ILOGBNAN 0x7fffffff + + static_assert(__SIZEOF_LONG_DOUBLE__ >= __SIZEOF_DOUBLE__, + "Error: Configuration error regarding 64-bit double/long-double for AVR"); + + #if(__SIZEOF_DOUBLE__ == 4) + #define __BUILTIN_ISNANF __builtin_isnan + #define __BUILTIN_ISNAN __builtin_isnan + #define __BUILTIN_ISNANL __builtin_isnanl + #define __BUILTIN_FABSF __builtin_fabs + #define __BUILTIN_FABS __builtin_fabs + #define __BUILTIN_FABSL __builtin_fabsl + #define __BUILTIN_FMODF __builtin_fmod + #define __BUILTIN_FMOD __builtin_fmod + #define __BUILTIN_FMODL __builtin_fmodl + #define __BUILTIN_MODFF __builtin_modff + #define __BUILTIN_MODF __builtin_modf + #define __BUILTIN_MODFL __builtin_modfl + #define __BUILTIN_FLOORF __builtin_floor + #define __BUILTIN_FLOOR __builtin_floor + #define __BUILTIN_FLOORL __builtin_floorl + #define __BUILTIN_CEILF __builtin_ceil + #define __BUILTIN_CEIL __builtin_ceil + #define __BUILTIN_CEILL __builtin_ceill + #define __BUILTIN_FREXPF __builtin_frexp + #define __BUILTIN_FREXP __builtin_frexp + #define __BUILTIN_FREXPL __builtin_frexpl + #define __BUILTIN_LDEXPF __builtin_ldexp + #define __BUILTIN_LDEXP __builtin_ldexp + #define __BUILTIN_LDEXPL __builtin_ldexpl + #define __BUILTIN_LROUNDF __builtin_lround + #define __BUILTIN_LROUND __builtin_lround + #define __BUILTIN_LROUNDL __builtin_lroundl + #define __BUILTIN_SQRTF __builtin_sqrt + #define __BUILTIN_SQRT __builtin_sqrt + #define __BUILTIN_SQRTL __builtin_sqrtl + #define __BUILTIN_CBRTF __builtin_cbrt + #define __BUILTIN_CBRT __builtin_cbrt + #define __BUILTIN_CBRTL __builtin_cbrtl + #define __BUILTIN_SINF __builtin_sin + #define __BUILTIN_SIN __builtin_sin + #define __BUILTIN_SINL __builtin_sinl + #define __BUILTIN_COSF __builtin_cos + #define __BUILTIN_COS __builtin_cos + #define __BUILTIN_COSL __builtin_cosl + #define __BUILTIN_TANF __builtin_tan + #define __BUILTIN_TAN __builtin_tan + #define __BUILTIN_TANL __builtin_tanl + #define __BUILTIN_ASINF __builtin_asin + #define __BUILTIN_ASIN __builtin_asin + #define __BUILTIN_ASINL __builtin_asinl + #define __BUILTIN_ACOSF __builtin_acos + #define __BUILTIN_ACOS __builtin_acos + #define __BUILTIN_ACOSL __builtin_acosl + #define __BUILTIN_ATANF __builtin_atan + #define __BUILTIN_ATAN __builtin_atan + #define __BUILTIN_ATANL __builtin_atanl + #define __BUILTIN_ATAN2F __builtin_atan2 + #define __BUILTIN_ATAN2 __builtin_atan2 + #define __BUILTIN_ATAN2L __builtin_atan2l + #define __BUILTIN_EXPF __builtin_exp + #define __BUILTIN_EXP __builtin_exp + #define __BUILTIN_EXPL __builtin_expl + #define __BUILTIN_POWF __builtin_pow + #define __BUILTIN_POW __builtin_pow + #define __BUILTIN_POWL __builtin_powl + #define __BUILTIN_LOGF __builtin_log + #define __BUILTIN_LOG __builtin_log + #define __BUILTIN_LOGL __builtin_logl + #define __BUILTIN_LOG10F __builtin_log10 + #define __BUILTIN_LOG10 __builtin_log10 + #define __BUILTIN_LOG10L __builtin_log10l + #define __BUILTIN_SINHF __builtin_sinh + #define __BUILTIN_SINH __builtin_sinh + #define __BUILTIN_SINHL __builtin_sinhl + #define __BUILTIN_COSHF __builtin_cosh + #define __BUILTIN_COSH __builtin_cosh + #define __BUILTIN_COSHL __builtin_coshl + #define __BUILTIN_TANHF __builtin_tanh + #define __BUILTIN_TANH __builtin_tanh + #define __BUILTIN_TANHL __builtin_tanhl + #elif(__SIZEOF_DOUBLE__ == 8) + #define __BUILTIN_ISNANF __builtin_isnanf + #define __BUILTIN_ISNAN __builtin_isnanl + #define __BUILTIN_ISNANL __builtin_isnanl + #define __BUILTIN_FABSF __builtin_fabsf + #define __BUILTIN_FABS __builtin_fabsl + #define __BUILTIN_FABSL __builtin_fabsl + #define __BUILTIN_FMODF __builtin_fmodf + #define __BUILTIN_FMOD __builtin_fmodl + #define __BUILTIN_FMODL __builtin_fmodl + #define __BUILTIN_MODFF __builtin_modff + #define __BUILTIN_MODF __builtin_modf + #define __BUILTIN_MODFL __builtin_modfl + #define __BUILTIN_FLOORF __builtin_floorf + #define __BUILTIN_FLOOR __builtin_floorl + #define __BUILTIN_FLOORL __builtin_floorl + #define __BUILTIN_CEILF __builtin_ceilf + #define __BUILTIN_CEIL __builtin_ceill + #define __BUILTIN_CEILL __builtin_ceill + #define __BUILTIN_FREXPF __builtin_frexpf + #define __BUILTIN_FREXP __builtin_frexpl + #define __BUILTIN_FREXPL __builtin_frexpl + #define __BUILTIN_LDEXPF __builtin_ldexpf + #define __BUILTIN_LDEXP __builtin_ldexpl + #define __BUILTIN_LDEXPL __builtin_ldexpl + #define __BUILTIN_LROUNDF __builtin_lroundf + #define __BUILTIN_LROUND __builtin_lroundl + #define __BUILTIN_LROUNDL __builtin_lroundl + #define __BUILTIN_SQRTF __builtin_sqrtf + #define __BUILTIN_SQRT __builtin_sqrtl + #define __BUILTIN_SQRTL __builtin_sqrtl + #define __BUILTIN_CBRTF __builtin_cbrtf + #define __BUILTIN_CBRT __builtin_cbrtl + #define __BUILTIN_CBRTL __builtin_cbrtl + #define __BUILTIN_SINF __builtin_sinf + #define __BUILTIN_SIN __builtin_sinl + #define __BUILTIN_SINL __builtin_sinl + #define __BUILTIN_COSF __builtin_cosf + #define __BUILTIN_COS __builtin_cosl + #define __BUILTIN_COSL __builtin_cosl + #define __BUILTIN_TANF __builtin_tanf + #define __BUILTIN_TAN __builtin_tanl + #define __BUILTIN_TANL __builtin_tanl + #define __BUILTIN_ASINF __builtin_asinf + #define __BUILTIN_ASIN __builtin_asinl + #define __BUILTIN_ASINL __builtin_asinl + #define __BUILTIN_ACOSF __builtin_acosf + #define __BUILTIN_ACOS __builtin_acosl + #define __BUILTIN_ACOSL __builtin_acosl + #define __BUILTIN_ATANF __builtin_atanf + #define __BUILTIN_ATAN __builtin_atanl + #define __BUILTIN_ATANL __builtin_atanl + #define __BUILTIN_ATAN2F __builtin_atan2f + #define __BUILTIN_ATAN2 __builtin_atan2l + #define __BUILTIN_ATAN2L __builtin_atan2l + #define __BUILTIN_EXPF __builtin_expf + #define __BUILTIN_EXP __builtin_expl + #define __BUILTIN_EXPL __builtin_expl + #define __BUILTIN_POWF __builtin_powf + #define __BUILTIN_POW __builtin_powl + #define __BUILTIN_POWL __builtin_powl + #define __BUILTIN_LOGF __builtin_logf + #define __BUILTIN_LOG __builtin_logl + #define __BUILTIN_LOGL __builtin_logl + #define __BUILTIN_LOG10F __builtin_log10f + #define __BUILTIN_LOG10 __builtin_log10l + #define __BUILTIN_LOG10L __builtin_log10l + #define __BUILTIN_SINHF __builtin_sinhf + #define __BUILTIN_SINH __builtin_sinhl + #define __BUILTIN_SINHL __builtin_sinhl + #define __BUILTIN_COSHF __builtin_coshf + #define __BUILTIN_COSH __builtin_coshl + #define __BUILTIN_COSHL __builtin_coshl + #define __BUILTIN_TANHF __builtin_tanhf + #define __BUILTIN_TANH __builtin_tanhl + #define __BUILTIN_TANHL __builtin_tanhl #else + #error Error: sizeof(double) is unknown or not standard for AVR. + #endif - #include - - namespace std - { - inline float abs(float x) { return ::fabsf(x); } - inline double abs(double x) { return ::fabs (x); } - inline long double abs(long double x) { return ::fabsl(x); } - - using ::fabs; - using ::fmod; - using ::modf; - using ::floor; - using ::ceil; - using ::frexp; - using ::ldexp; - using ::sqrt; - using ::sin; - using ::cos; - using ::tan; - using ::asin; - using ::acos; - using ::atan; - using ::atan2; - using ::exp; - using ::pow; - using ::log; - using ::log10; - using ::sinh; - using ::cosh; - using ::tanh; - } - - #endif // __GNUC__ or not __GNUC__ stuff + extern "C" + { + //int isfinitef(float x); + int isfinitel(long double x); + int ilogbf(float x); + int ilogb (double x); + int ilogbl(long double x); + + float asinhf(float x); + double asinh (double x); + long double asinhl(long double x); + + float acoshf(float x); + double acosh (double x); + long double acoshl(long double x); + + float atanhf(float x); + double atanh (double x); + long double atanhl(long double x); + + float tgammaf(float x); + double tgamma (double x); + long double tgammal(long double x); + + float lgammaf(float x); + double lgamma (double x); + long double lgammal(long double x); + } namespace std { - // Provide certain functions that are often missing from . - // Here, we patch some of these in an exemplary fashion for the - // proposed std::float32_t. - float32_t asinh (std::float32_t x); - float32_t acosh (std::float32_t x); - float32_t atanh (std::float32_t x); - float32_t tgamma(std::float32_t x); + inline bool isfinite(float x) { return ::isfinitef(x) == 1; } + inline bool isfinite(double x) { return ::isfinite (x) == 1; } + inline bool isfinite(long double x) { return ::isfinitel(x) == 1; } + inline int ilogb (float x) { return ::ilogbf (x); } + inline int ilogb (double x) { return ::ilogb (x); } + inline int ilogb (long double x) { return ::ilogbl (x); } + inline bool isnan (float x) { return __BUILTIN_ISNANF (x) == 1; } + inline bool isnan (double x) { return __BUILTIN_ISNAN (x) == 1; } + inline bool isnan (long double x) { return __BUILTIN_ISNANL (x) == 1; } + inline float fabs (float x) { return __BUILTIN_FABSF (x); } + inline double fabs (double x) { return __BUILTIN_FABS (x); } + inline long double fabs (long double x) { return __BUILTIN_FABSL (x); } + inline float fmod (float x, float y) { return __BUILTIN_FMODF (x, y); } + inline double fmod (double x, double y) { return __BUILTIN_FMOD (x, y); } + inline long double fmod (long double x, long double y) { return __BUILTIN_FMODL (x, y); } + inline float modf (float x, float* intptr) { return __BUILTIN_MODFF (x, intptr); } + inline double modf (double x, double* intptr) { return __BUILTIN_MODF (x, intptr); } + inline long double modf (long double x, long double* intptr) { return __BUILTIN_MODFL (x, intptr); } + inline float floor (float x) { return __BUILTIN_FLOORF(x); } + inline double floor (double x) { return __BUILTIN_FLOOR (x); } + inline long double floor (long double x) { return __BUILTIN_FLOORL(x); } + inline float ceil (float x) { return __BUILTIN_CEILF (x); } + inline double ceil (double x) { return __BUILTIN_CEIL (x); } + inline long double ceil (long double x) { return __BUILTIN_CEILL (x); } + inline float frexp (float x, int* p) { return __BUILTIN_FREXPF(x, p); } + inline double frexp (double x, int* p) { return __BUILTIN_FREXP (x, p); } + inline long double frexp (long double x, int* p) { return __BUILTIN_FREXPL(x, p); } + inline float ldexp (float x, int p) { return __BUILTIN_LDEXPF(x, p); } + inline double ldexp (double x, int p) { return __BUILTIN_LDEXP (x, p); } + inline long double ldexp (long double x, int p) { return __BUILTIN_LDEXPL(x, p); } + inline long lround (float x) { return __BUILTIN_LROUNDF(x); } + inline long lround (double x) { return __BUILTIN_LROUND (x); } + inline long lround (long double x) { return __BUILTIN_LROUNDL(x); } + inline float sqrt (float x) { return __BUILTIN_SQRTF (x); } + inline double sqrt (double x) { return __BUILTIN_SQRT (x); } + inline long double sqrt (long double x) { return __BUILTIN_SQRTL (x); } + inline float cbrt (float x) { return __BUILTIN_CBRTF (x); } + inline double cbrt (double x) { return __BUILTIN_CBRT (x); } + inline long double cbrt (long double x) { return __BUILTIN_CBRTL (x); } + inline float sin (float x) { return __BUILTIN_SINF (x); } + inline double sin (double x) { return __BUILTIN_SIN (x); } + inline long double sin (long double x) { return __BUILTIN_SINL (x); } + inline float cos (float x) { return __BUILTIN_COSF (x); } + inline double cos (double x) { return __BUILTIN_COS (x); } + inline long double cos (long double x) { return __BUILTIN_COSL (x); } + inline float tan (float x) { return __BUILTIN_TANF (x); } + inline double tan (double x) { return __BUILTIN_TAN (x); } + inline long double tan (long double x) { return __BUILTIN_TANL (x); } + inline float asin (float x) { return __BUILTIN_ASINF (x); } + inline double asin (double x) { return __BUILTIN_ASIN (x); } + inline long double asin (long double x) { return __BUILTIN_ASINL (x); } + inline float acos (float x) { return __BUILTIN_ACOSF (x); } + inline double acos (double x) { return __BUILTIN_ACOS (x); } + inline long double acos (long double x) { return __BUILTIN_ACOSL (x); } + inline float atan (float x) { return __BUILTIN_ATANF (x); } + inline double atan (double x) { return __BUILTIN_ATAN (x); } + inline long double atan (long double x) { return __BUILTIN_ATANL (x); } + inline float atan2 (float y, float x) { return __BUILTIN_ATAN2F(y, x); } + inline double atan2 (double y, double x) { return __BUILTIN_ATAN2 (y, x); } + inline long double atan2 (long double y, long double x) { return __BUILTIN_ATAN2L(y, x); } + inline float exp (float x) { return __BUILTIN_EXPF (x); } + inline double exp (double x) { return __BUILTIN_EXP (x); } + inline long double exp (long double x) { return __BUILTIN_EXPL (x); } + inline float pow (float x, float a) { return __BUILTIN_POWF (x, a); } + inline double pow (double x, double a) { return __BUILTIN_POW (x, a); } + inline long double pow (long double x, long double a) { return __BUILTIN_POWL (x, a); } + inline float log (float x) { return __BUILTIN_LOGF (x); } + inline double log (double x) { return __BUILTIN_LOG (x); } + inline long double log (long double x) { return __BUILTIN_LOGL (x); } + inline float log10 (float x) { return __BUILTIN_LOG10F(x); } + inline double log10 (double x) { return __BUILTIN_LOG10 (x); } + inline long double log10 (long double x) { return __BUILTIN_LOG10L(x); } + inline float sinh (float x) { return __BUILTIN_SINHF (x); } + inline double sinh (double x) { return __BUILTIN_SINH (x); } + inline long double sinh (long double x) { return __BUILTIN_SINHL (x); } + inline float cosh (float x) { return __BUILTIN_COSHF (x); } + inline double cosh (double x) { return __BUILTIN_COSH (x); } + inline long double cosh (long double x) { return __BUILTIN_COSHL (x); } + inline float tanh (float x) { return __BUILTIN_TANHF (x); } + inline double tanh (double x) { return __BUILTIN_TANH (x); } + inline long double tanh (long double x) { return __BUILTIN_TANHL (x); } + inline float asinh (float x) { return ::asinhf(x); } + inline double asinh (double x) { return ::asinh (x); } + inline long double asinh (long double x) { return ::asinhl(x); } + inline float acosh (float x) { return ::acoshf(x); } + inline double acosh (double x) { return ::acosh (x); } + inline long double acosh (long double x) { return ::acoshl(x); } + inline float atanh (float x) { return ::asinhf(x); } + inline double atanh (double x) { return ::asinh (x); } + inline long double atanh (long double x) { return ::asinhl(x); } + inline float tgamma (float x) { return ::tgammaf(x); } + inline double tgamma (double x) { return ::tgamma (x); } + inline long double tgamma (long double x) { return ::tgammal(x); } + inline float lgamma (float x) { return ::lgammaf(x); } + inline double lgamma (double x) { return ::lgamma (x); } + inline long double lgamma (long double x) { return ::lgammal(x); } } + #else + + #if defined(__cplusplus) + extern "C" + { + #endif + // These are (most of) the functions from having C-linkage. + int isfinitef(float); + int isfinitel(long double); + int ilogbf (float); + int ilogbl (long double); + int isnanf (float); + int isnanl (long double); + float fabsf (float x); + long double fabsl (long double x); + float fmodf (float x, float y); + long double fmodl (long double x, long double y); + float modff (float x, float* intptr); + long double modfl (long double x, long double* intptr); + float floorf (float x); + long double floorl (long double x); + float ceilf (float x); + long double ceill (long double x); + float frexpf (float x, int* p); + long double frexpl (long double x, int* p); + float ldexpf (float x, int p); + long double ldexpl (long double x, int p); + long lroundf (float x); + long lroundl (long double x); + float sqrtf (float x); + long double sqrtl (long double x); + float cbrtf (float x); + long double cbrtl (long double x); + float sinf (float x); + long double sinl (long double x); + float cosf (float x); + long double cosl (long double x); + float tanf (float x); + long double tanl (long double x); + float asinf (float x); + long double asinl (long double x); + float acosf (float x); + long double acosl (long double x); + float atanf (float x); + long double atanl (long double x); + float atan2f (float y, float x); + long double atan2l (long double y, long double x); + float expf (float x); + long double expl (long double x); + float powf (float x, float a); + long double powl (long double x, long double a); + float logf (float x); + long double logl (long double x); + float log10f (float x); + long double log10l (long double x); + float sinhf (float x); + long double sinhl (long double x); + float coshf (float x); + long double coshl (long double x); + float tanhf (float x); + long double tanhl (long double x); + float asinhf (float x); + long double asinhl (long double x); + float acoshf (float x); + long double acoshl (long double x); + float atanhf (float x); + long double atanhl (long double x); + float tgammaf (float x); + long double tgammal (long double x); + float lgammaf (float x); + long double lgammal (long double x); + #if defined(__cplusplus) + } + #endif + + #if defined(__cplusplus) + extern "C++" + { + #endif + inline bool isfinite(float x) { return (::isfinitef(x) == 1); } + inline bool isfinite(double x) { return (::isfinite (x) == 1); } + inline bool isfinite(long double x) { return (::isfinitel(x) == 1); } + inline int ilogb (float x) { return ::ilogbf(x); } + inline int ilogb (double x) { return ::ilogb (x); } + inline int ilogb (long double x) { return ::ilogbl(x); } + #if (defined(__GNUC__) && !defined(__clang__)) + inline bool isnan (float x) { return __builtin_isnanf(x); } + inline bool isnan (double x) { return __builtin_isnan (x); } + inline bool isnan (long double x) { return __builtin_isnanl(x); } + inline float abs (float x) { return __builtin_fabsf (x); } + inline double abs (double x) { return __builtin_fabs (x); } + inline long double abs (long double x) { return __builtin_fabsl (x); } + inline float fabs (float x) { return __builtin_fabsf (x); } + inline double fabs (double x) { return __builtin_fabs (x); } + inline long double fabs (long double x) { return __builtin_fabsl (x); } + inline float fmod (float x, float y) { return __builtin_fmodf (x, y); } + inline double fmod (double x, double y) { return __builtin_fmod (x, y); } + inline long double fmod (long double x, long double y) { return __builtin_fmodl (x, y); } + inline float modf (float x, float* p) { return __builtin_modff (x, p); } + inline double modf (double x, double* p) { return __builtin_modf (x, p); } + inline long double modf (long double x, long double* p) { return __builtin_modfl (x, p); } + inline float floor (float x) { return __builtin_floorf(x); } + inline double floor (double x) { return __builtin_floor (x); } + inline long double floor (long double x) { return __builtin_floorl(x); } + inline float ceil (float x) { return __builtin_ceilf (x); } + inline double ceil (double x) { return __builtin_ceil (x); } + inline long double ceil (long double x) { return __builtin_ceill (x); } + inline float frexp (float x, int* p) { return __builtin_frexpf(x, p); } + inline double frexp (double x, int* p) { return __builtin_frexp (x, p); } + inline long double frexp (long double x, int* p) { return __builtin_frexpl(x, p); } + inline float ldexp (float x, int p) { return __builtin_ldexpf(x, p); } + inline double ldexp (double x, int p) { return __builtin_ldexp (x, p); } + inline long double ldexp (long double x, int p) { return __builtin_ldexpl(x, p); } + inline long lround (float x) { return __builtin_lroundf(x); } + inline long lround (double x) { return __builtin_lround (x); } + inline long lround (long double x) { return __builtin_lroundl(x); } + inline float sqrt (float x) { return __builtin_sqrtf (x); } + inline double sqrt (double x) { return __builtin_sqrt (x); } + inline long double sqrt (long double x) { return __builtin_sqrtl (x); } + inline float cbrt (float x) { return __builtin_cbrtf (x); } + inline double cbrt (double x) { return __builtin_cbrt (x); } + inline long double cbrt (long double x) { return __builtin_cbrtl (x); } + inline float sin (float x) { return __builtin_sinf (x); } + inline double sin (double x) { return __builtin_sin (x); } + inline long double sin (long double x) { return __builtin_sinl (x); } + inline float cos (float x) { return __builtin_cosf (x); } + inline double cos (double x) { return __builtin_cos (x); } + inline long double cos (long double x) { return __builtin_cosl (x); } + inline float tan (float x) { return __builtin_tanf (x); } + inline double tan (double x) { return __builtin_tan (x); } + inline long double tan (long double x) { return __builtin_tanl (x); } + inline float asin (float x) { return __builtin_asinf (x); } + inline double asin (double x) { return __builtin_asin (x); } + inline long double asin (long double x) { return __builtin_asinl (x); } + inline float acos (float x) { return __builtin_acosf (x); } + inline double acos (double x) { return __builtin_acos (x); } + inline long double acos (long double x) { return __builtin_acosl (x); } + inline float atan (float x) { return __builtin_atanf (x); } + inline double atan (double x) { return __builtin_atan (x); } + inline long double atan (long double x) { return __builtin_atanl (x); } + inline float atan2 (float y, float x) { return __builtin_atan2f(y, x); } + inline double atan2 (double y, double x) { return __builtin_atan2 (y, x); } + inline long double atan2 (long double y, long double x) { return __builtin_atan2l(y, x); } + inline float exp (float x) { return __builtin_expf (x); } + inline double exp (double x) { return __builtin_exp (x); } + inline long double exp (long double x) { return __builtin_expl (x); } + inline float pow (float x, float a) { return __builtin_powf (x, a); } + inline double pow (double x, double a) { return __builtin_pow (x, a); } + inline long double pow (long double x, long double a) { return __builtin_powl (x, a); } + inline float log (float x) { return __builtin_logf (x); } + inline double log (double x) { return __builtin_log (x); } + inline long double log (long double x) { return __builtin_logl (x); } + inline float log10 (float x) { return __builtin_log10f(x); } + inline double log10 (double x) { return __builtin_log10 (x); } + inline long double log10 (long double x) { return __builtin_log10l(x); } + inline float sinh (float x) { return __builtin_sinhf (x); } + inline double sinh (double x) { return __builtin_sinh (x); } + inline long double sinh (long double x) { return __builtin_sinhl (x); } + inline float cosh (float x) { return __builtin_coshf (x); } + inline double cosh (double x) { return __builtin_cosh (x); } + inline long double cosh (long double x) { return __builtin_coshl (x); } + inline float tanh (float x) { return __builtin_tanhf (x); } + inline double tanh (double x) { return __builtin_tanh (x); } + inline long double tanh (long double x) { return __builtin_tanhl (x); } + #else + inline bool isnan (float x) { return ::isnanf(x); } + bool isnan (double x); + inline bool isnan (long double x) { return ::isnanl(x); } + inline float abs (float x) { return ::fabsf (x); } + extern "C" + double abs (double x); + inline long double abs (long double x) { return ::fabsl (x); } + inline float fabs (float x) { return ::fabsf (x); } + extern "C" + double fabs (double x); + inline long double fabs (long double x) { return ::fabsl (x); } + inline float fmod (float x, float y) { return ::fmodf(x, y); } + extern "C" + double fmod (double x, double y); + inline long double fmod (long double x, long double y) { return ::fmodl(x, y); } + inline float modf (float x, float* p) { return ::modff (x, p); } + extern "C" + double modf (double x, double* p); + inline long double modf (long double x, long double* p) { return ::modfl (x, p); } + inline float floor (float x) { return ::floorf(x); } + extern "C" + double floor (double x); + inline long double floor (long double x) { return ::floorl(x); } + inline float ceil (float x) { return ::ceilf (x); } + extern "C" + double ceil (double x); + inline long double ceil (long double x) { return ::ceill (x); } + inline float frexp (float x, int* p) { return ::frexpf(x, p); } + extern "C" + double frexp (double x, int* p); + inline long double frexp (long double x, int* p) { return ::frexpl(x, p); } + inline float ldexp (float x, int p) { return ::ldexpf(x, p); } + extern "C" + double ldexp (double x, int p); + inline long double ldexp (long double x, int p) { return ::ldexpl (x, p); } + inline long lround (float x) { return ::lroundf(x); } + extern "C" + long lround (double x); + inline long lround (long double x) { return ::lroundl(x); } + inline float sqrt (float x) { return ::sqrtf (x); } + extern "C" + double sqrt (double x); + inline long double sqrt (long double x) { return ::sqrtl (x); } + inline float cbrt (float x) { return ::cbrtf (x); } + extern "C" + double cbrt (double x); + inline long double cbrt (long double x) { return ::cbrtl (x); } + inline float sin (float x) { return ::sinf (x); } + extern "C" + double sin (double x); + inline long double sin (long double x) { return ::sinl (x); } + inline float cos (float x) { return ::cosf (x); } + extern "C" + double cos (double x); + inline long double cos (long double x) { return ::cosl (x); } + inline float tan (float x) { return ::tanf (x); } + extern "C" + double tan (double x); + inline long double tan (long double x) { return ::tanl (x); } + inline float asin (float x) { return ::asinf (x); } + extern "C" + double asin (double x); + inline long double asin (long double x) { return ::asinl (x); } + inline float acos (float x) { return ::acosf (x); } + extern "C" + double acos (double x); + inline long double acos (long double x) { return ::acosl (x); } + inline float atan (float x) { return ::atanf (x); } + extern "C" + double atan (double x); + inline long double atan (long double x) { return ::atanl (x); } + inline float atan2 (float y, float x) { return ::atan2f(y, x); } + extern "C" + double atan2 (double y, double x); + inline long double atan2 (long double y, long double x) { return ::atan2l(y, x); } + inline float exp (float x) { return ::expf (x); } + extern "C" + double exp (double x); + inline long double exp (long double x) { return ::expl (x); } + inline float pow (float x, float a) { return ::powf (x, a); } + extern "C" + double pow (double x, double a); + inline long double pow (long double x, long double a) { return ::powl (x, a); } + inline float log (float x) { return ::logf (x); } + extern "C" + double log (double x); + inline long double log (long double x) { return ::logl (x); } + inline float log10 (float x) { return ::log10f(x); } + extern "C" + double log10 (double x); + inline long double log10 (long double x) { return ::log10l(x); } + inline float sinh (float x) { return ::sinhf (x); } + extern "C" + double sinh (double x); + inline long double sinh (long double x) { return ::sinhl (x); } + inline float cosh (float x) { return ::coshf (x); } + extern "C" + double cosh (double x); + inline long double cosh (long double x) { return ::coshl (x); } + inline float tanh (float x) { return ::tanhf (x); } + extern "C" + double tanh (double x); + inline long double tanh (long double x) { return ::tanhl (x); } + #endif + inline float asinh (float x) { return ::asinhf(x); } + extern "C" + double asinh (double x); + inline long double asinh (long double x) { return ::asinhl(x); } + inline float acosh (float x) { return ::acoshf(x); } + extern "C" + double acosh (double x); + inline long double acosh (long double x) { return ::acoshl(x); } + inline float atanh (float x) { return ::atanhf(x); } + extern "C" + double atanh (double x); + inline long double atanh (long double x) { return ::atanhl(x); } + inline float tgamma (float x) { return ::tgammaf(x); } + extern "C" + double tgamma (double x); + inline long double tgamma (long double x) { return ::tgammal(x); } + inline float lgamma (float x) { return ::lgammaf(x); } + extern "C" + double lgamma (double x); + inline long double lgamma (long double x) { return ::lgammal(x); } + #if __cplusplus > 201703L + inline float lerp (float a, float b, float t) + { return a + (t * (b - a)); } + inline double lerp (double a, double b, double t) + { return a + (t * (b - a)); } + inline long double lerp (long double a, long double b, long double t) + { return a + (t * (b - a)); } + #endif + #if defined(__cplusplus) + } + #endif + + namespace std + { + using ::isfinite; + using ::ilogb; + using ::isnan; + using ::abs; + using ::fabs; + using ::fmod; + using ::modf; + using ::floor; + using ::ceil; + using ::frexp; + using ::ldexp; + using ::lround; + using ::sqrt; + using ::cbrt; + using ::sin; + using ::cos; + using ::tan; + using ::asin; + using ::acos; + using ::atan; + using ::atan2; + using ::exp; + using ::pow; + using ::log; + using ::log10; + using ::sinh; + using ::cosh; + using ::tanh; + using ::asinh; + using ::acosh; + using ::atanh; + using ::tgamma; + using ::lgamma; + } // namespace std + + #endif + #endif // CMATH_2010_02_23_ diff --git a/examples/chapter11_07/src/util/STL/complex b/examples/chapter11_07/src/util/STL/complex index af71423d8..7d6117896 100644 --- a/examples/chapter11_07/src/util/STL/complex +++ b/examples/chapter11_07/src/util/STL/complex @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -1230,10 +1230,10 @@ const bool __my_real_part_is_neg(__my_z.real() < 0U); - const T __my_real_part_fabs((__my_real_part_is_neg == false) ? __my_z.real() : -__my_z.real()); + const T __my_real_part_fabs((!__my_real_part_is_neg) ? __my_z.real() : -__my_z.real()); const T __my_sqrt_part (sqrt((__my_real_part_fabs + abs(__my_z)) / 2U)); - if(__my_real_part_is_neg == false) + if(!__my_real_part_is_neg) { return complex(__my_sqrt_part, __my_z.imag() / (__my_sqrt_part * 2U)); @@ -1242,10 +1242,10 @@ { const bool __my_imag_part_is_neg(__my_z.imag() < 0U); - const T __my_imag_part_fabs((__my_imag_part_is_neg == false) ? __my_z.imag() : -__my_z.imag()); + const T __my_imag_part_fabs((!__my_imag_part_is_neg) ? __my_z.imag() : -__my_z.imag()); return complex( __my_imag_part_fabs / (__my_sqrt_part * 2U), - ((__my_imag_part_is_neg == false) ? __my_sqrt_part : -__my_sqrt_part)); + ((!__my_imag_part_is_neg) ? __my_sqrt_part : -__my_sqrt_part)); } } @@ -1287,7 +1287,7 @@ } // namespace std /* - 8-bit microcontroller @ 16MHz + 8-bit microcontroller at 16MHz std::complex x(1.23F, 3.45F); std::complex y(0.77F, 0.22F); diff --git a/examples/chapter11_07/src/util/STL/cstdbool b/examples/chapter11_07/src/util/STL/cstdbool index 833781c82..35fbdae3b 100644 --- a/examples/chapter11_07/src/util/STL/cstdbool +++ b/examples/chapter11_07/src/util/STL/cstdbool @@ -8,15 +8,18 @@ #ifndef CSTDBOOL_2012_12_14_ #define CSTDBOOL_2012_12_14_ - #include + #if (!defined(__cplusplus) && !defined(__bool_true_false_are_defined)) + + #define bool _Bool + #define false 0 + #define true 1 + + #define __bool_true_false_are_defined 1 + + #endif #if !defined(__bool_true_false_are_defined) #define __bool_true_false_are_defined 1 #endif - namespace std - { - using ::bool; - } - #endif // CSTDBOOL_2012_12_14_ diff --git a/examples/chapter11_07/src/util/STL/cstdint b/examples/chapter11_07/src/util/STL/cstdint index 1e030cf28..0e2e8d7ed 100644 --- a/examples/chapter11_07/src/util/STL/cstdint +++ b/examples/chapter11_07/src/util/STL/cstdint @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) @@ -49,35 +49,36 @@ namespace std { - using ::int8_t; - using ::int16_t; - using ::int32_t; - using ::int64_t; + using ::int8_t; + using ::int16_t; + using ::int32_t; + using ::int64_t; using ::uint8_t; using ::uint16_t; using ::uint32_t; using ::uint64_t; - using ::int_least8_t; - using ::int_least16_t; - using ::int_least32_t; - using ::int_least64_t; + using ::int_least8_t; + using ::int_least16_t; + using ::int_least32_t; + using ::int_least64_t; using ::uint_least8_t; using ::uint_least16_t; using ::uint_least32_t; using ::uint_least64_t; - using ::int_fast8_t; - using ::int_fast16_t; - using ::int_fast32_t; - using ::int_fast64_t; + using ::int_fast8_t; + using ::int_fast16_t; + using ::int_fast32_t; + using ::int_fast64_t; using ::uint_fast8_t; using ::uint_fast16_t; using ::uint_fast32_t; using ::uint_fast64_t; - using ::intmax_t; + using ::intmax_t; using ::uintmax_t; + using ::intptr_t; using ::uintptr_t; } diff --git a/examples/chapter11_07/src/util/STL/cstdlib b/examples/chapter11_07/src/util/STL/cstdlib index 83e04fe69..0055579ac 100644 --- a/examples/chapter11_07/src/util/STL/cstdlib +++ b/examples/chapter11_07/src/util/STL/cstdlib @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2017. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -29,15 +29,31 @@ #define EXIT_FAILURE -1 #endif - void exit(int) __attribute__((noreturn)); + extern "C" + { + void abort (void); + int atexit(void(*)(void)) noexcept; + void exit (int); + float strtof(const char* str, char** str_end); + double strtod(const char* str, char** str_end); + long double strtold(const char* str, char** str_end); + } namespace std { inline int abs(int a) { return ((a < 0) ? -a : a); } + //inline long abs(long a) { return ((a < 0) ? -a : a); } + //inline long long abs(long long a) { return ((a < 0) ? -a : a); } inline long labs(long a) { return ((a < 0) ? -a : a); } inline long long llabs(long long a) { return ((a < 0) ? -a : a); } - inline void exit(int exit_code) { ::exit(exit_code); } + using ::abort; + using ::atexit; + using ::exit; + + using ::strtof; + using ::strtod; + using ::strtold; struct div_t { int quot; int rem; }; struct ldiv_t { long quot; long rem; }; diff --git a/examples/chapter11_07/src/util/STL/cstring b/examples/chapter11_07/src/util/STL/cstring index e2b079384..3a899f75e 100644 --- a/examples/chapter11_07/src/util/STL/cstring +++ b/examples/chapter11_07/src/util/STL/cstring @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -10,15 +10,20 @@ #include - extern "C" void* memset(void*, int, size_t); - extern "C" size_t strlen(const char*); - extern "C" char* strcpy(char*, const char*); + extern "C" void* memcpy (void*, const void*, size_t); + extern "C" void* memmove(void*, const void*, size_t); + extern "C" void* memset (void*, int, size_t); + + extern "C" char* strcpy (char*, const char*); + extern "C" size_t strlen (const char*); namespace std { - inline void* memset(void* dst, int c, size_t n) { return ::memset(dst, c, n); } - inline ::size_t strlen(const char* str) { return ::strlen(str); } - inline char* strcpy(char* p_dst, const char* p_src) { return ::strcpy(p_dst, p_src); } + using ::memcpy; + using ::memmove; + using ::memset; + using ::strlen; + using ::strcpy; } #endif // CSTRING_2018_10_04_ diff --git a/examples/chapter11_07/src/util/STL/functional b/examples/chapter11_07/src/util/STL/functional index 4d04b4e38..ca8441843 100644 --- a/examples/chapter11_07/src/util/STL/functional +++ b/examples/chapter11_07/src/util/STL/functional @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -14,6 +14,16 @@ namespace std { + template + struct hash + { + // Since the underlying type is a std::uint64_t we will rely on its hash function from the STL + auto operator()(const T&) const noexcept -> std::size_t + { + return std::size_t { }; + } + }; + namespace xfunctional_impl { template constexpr T& func_ref_or_moveref(T& t) noexcept { return t; } @@ -28,7 +38,7 @@ template(std::declval()), - std::enable_if_t<(std::is_same>::value == false)>())> + std::enable_if_t<(!std::is_same>::value)>())> constexpr reference_wrapper(U&& u) noexcept(noexcept(xfunctional_impl::func_ref_or_moveref(std::forward(u)))) : my_ptr(std::addressof(xfunctional_impl::func_ref_or_moveref(std::forward(u)))) { } @@ -56,7 +66,7 @@ template struct identity { - typedef T type; + using type = T; }; template. + +#ifndef ALLOC_TRAITS_2021_01_26_H_ + #define ALLOC_TRAITS_2021_01_26_H_ + + #include + + #include + + + namespace std + { + template + class allocator; + + template + using __void_t = void; + + struct __allocator_traits_base + { + template + struct __rebind : __replace_first_arg<_Tp, _Up> { }; + + template + struct __rebind<_Tp, _Up, __void_t::other>> + { + using type = typename _Tp::template rebind<_Up>::other; + }; + + protected: + template + using __pointer = typename _Tp::pointer; + + template + using __c_pointer = typename _Tp::const_pointer; + + template + using __v_pointer = typename _Tp::void_pointer; + + template + using __cv_pointer = typename _Tp::const_void_pointer; + + template + using __pocca = typename _Tp::propagate_on_container_copy_assignment; + + template + using __pocma = typename _Tp::propagate_on_container_move_assignment; + + template + using __pocs = typename _Tp::propagate_on_container_swap; + + template + using __equal = typename _Tp::is_always_equal; + }; + + template + using __alloc_rebind = typename __allocator_traits_base::template __rebind::type; + + template + struct allocator_traits : __allocator_traits_base + { + public: + typedef AllocatorType allocator_type; + typedef typename AllocatorType::value_type value_type; + + using pointer = __detected_or_t; + + private: + template class _Func, typename _Tp, typename = void> + struct _Ptr + { + using type = typename pointer_traits::template rebind<_Tp>; + }; + + template class _Func, typename _Tp> + struct _Ptr<_Func, _Tp, __void_t<_Func>> + { + using type = _Func; + }; + + template + struct _Diff + { + using type = typename pointer_traits<_PtrT>::difference_type; + }; + + template + struct _Diff<_A2, _PtrT, __void_t> + { + using type = typename _A2::difference_type; + }; + + template + struct _Size + { + using type = size_t; + }; + + template + struct _Size<_A2, _DiffT, __void_t> + { + using type = typename _A2::size_type; + }; + + public: + using const_pointer = typename _Ptr<__c_pointer, const value_type>::type; + using void_pointer = typename _Ptr<__v_pointer, void>::type; + using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type; + using difference_type = typename _Diff::type; + using size_type = typename _Size::type; + + using propagate_on_container_swap = __detected_or_t; + + template + using rebind_alloc = __alloc_rebind; + + template + using rebind_traits = allocator_traits>; + + private: + template + static auto _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int) -> decltype(__a.allocate(__n, __hint)) + { + return __a.allocate(__n, __hint); + } + + template + static pointer _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...) + { + return __a.allocate(__n); + } + + template + struct __construct_helper + { + template()->construct( + std::declval<_Tp*>(), std::declval<_Args>()...))> + static true_type __test(int); + + template + static false_type __test(...); + + using type = decltype(__test(0)); + }; + + template + using __has_construct = typename __construct_helper<_Tp, _Args...>::type; + + template + static void _S_construct(AllocatorType& __a, _Tp* __p, _Args&&... __args) + { + __a.construct(__p, std::forward<_Args>(__args)...); + } + + template + static void _S_destroy(_Alloc2& __a, _Tp* __p, int) + { + __a.destroy(__p); + } + + template + static void _S_destroy(_Alloc2&, _Tp* __p, ...) + { + __p->~_Tp(); + } + + template + static size_type _S_max_size(_Alloc2& __a, int) + { + return __a.max_size(); + } + + template + static size_type _S_max_size(_Alloc2&, ...) + { + return (size_type) (0xFFFFFFFFFFFFFFFFULL / sizeof(value_type)); + } + + template + static auto _S_select(_Alloc2& __a, int) -> decltype(__a.select_on_container_copy_construction()) + { + return __a.select_on_container_copy_construction(); + } + + template + static _Alloc2 _S_select(_Alloc2& __a, ...) + { + return __a; + } + + public: + static pointer allocate(AllocatorType& __a, size_type __n) + { + return __a.allocate(__n); + } + + static pointer allocate(AllocatorType& __a, size_type __n, const_void_pointer __hint) + { + return _S_allocate(__a, __n, __hint, 0); + } + + static void deallocate(AllocatorType& __a, pointer __p, size_type __n) + { + __a.deallocate(__p, __n); + } + + template + static auto construct(AllocatorType& __a, _Tp* __p, _Args&&... __args) -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) + { + _S_construct(__a, __p, std::forward<_Args>(__args)...); + } + + template + static void destroy(AllocatorType& __a, _Tp* __p) + { + _S_destroy(__a, __p, 0); + } + + static size_type max_size(const AllocatorType& __a) noexcept + { return _S_max_size(__a, 0); } + + static AllocatorType + select_on_container_copy_construction(const AllocatorType& __rhs) + { return _S_select(__rhs, 0); } + }; + + template + struct allocator_traits> + { + // Partial specialization for std::allocator. + using allocator_type = allocator<_Tp>; + using value_type = _Tp; + using pointer = _Tp*; + using const_pointer = const _Tp*; + using void_pointer = void*; + using const_void_pointer = const void*; + using difference_type = std::ptrdiff_t; + using size_type = std::size_t; + using propagate_on_container_copy_assignment = false_type; + using propagate_on_container_move_assignment = true_type; + using propagate_on_container_swap = false_type; + using is_always_equal = true_type; + + template + using rebind_alloc = allocator<_Up>; + + template + using rebind_traits = allocator_traits>; + + static pointer allocate(allocator_type& __a, size_type __n) + { return __a.allocate(__n); } + + static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) + { return __a.allocate(__n, __hint); } + + static void deallocate(allocator_type& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + template + static void construct(allocator_type& __a, _Up* __p, _Args&&... __args) + { __a.construct(__p, std::forward<_Args>(__args)...); } + + template + static void destroy(allocator_type& __a, _Up* __p) noexcept(noexcept(__a.destroy(__p))) + { __a.destroy(__p); } + + static size_type max_size(const allocator_type& __a) noexcept + { return __a.max_size(); } + + static allocator_type select_on_container_copy_construction(const allocator_type& __rhs) + { return __rhs; } + }; + } + +#endif // ALLOC_TRAITS_2021_01_26_H_ diff --git a/examples/chapter11_07/src/util/STL/impl/arm/arm_float_limits.cpp b/examples/chapter11_07/src/util/STL/impl/arm/arm_float_limits.cpp deleted file mode 100644 index 5a7597274..000000000 --- a/examples/chapter11_07/src/util/STL/impl/arm/arm_float_limits.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. -// 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 - -namespace std -{ - namespace xfloat_impl - { - // Use some GCC internal stuff here. - STL_LOCAL_CONSTEXPR float avr_nan_flt = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR float avr_inf_flt = static_cast(__builtin_inf()); - STL_LOCAL_CONSTEXPR double avr_nan_dbl = __builtin_nan(""); - STL_LOCAL_CONSTEXPR double avr_inf_dbl = __builtin_inf(); - STL_LOCAL_CONSTEXPR long double avr_nan_ldbl = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR long double avr_inf_ldbl = static_cast(__builtin_inf()); - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_quiet_NaN() - { - return std::xfloat_impl::avr_nan_flt; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_signaling_NaN() - { - return 0.0F; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_infinity() - { - return std::xfloat_impl::avr_inf_flt; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_dbl; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_signaling_NaN() - { - return 0.0; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_infinity() - { - return std::xfloat_impl::avr_inf_dbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_ldbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_signaling_NaN() - { - return 0.0L; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_infinity() - { - return std::xfloat_impl::avr_inf_ldbl; - } -} diff --git a/examples/chapter11_07/src/util/STL/impl/avr/avr_atomic.h b/examples/chapter11_07/src/util/STL/impl/avr/avr_atomic.h index ba02a690e..7179cc287 100644 --- a/examples/chapter11_07/src/util/STL/impl/avr/avr_atomic.h +++ b/examples/chapter11_07/src/util/STL/impl/avr/avr_atomic.h @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) diff --git a/examples/chapter11_07/src/util/STL/impl/avr/avr_float_limits.cpp b/examples/chapter11_07/src/util/STL/impl/avr/avr_float_limits.cpp deleted file mode 100644 index 5a7597274..000000000 --- a/examples/chapter11_07/src/util/STL/impl/avr/avr_float_limits.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. -// 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 - -namespace std -{ - namespace xfloat_impl - { - // Use some GCC internal stuff here. - STL_LOCAL_CONSTEXPR float avr_nan_flt = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR float avr_inf_flt = static_cast(__builtin_inf()); - STL_LOCAL_CONSTEXPR double avr_nan_dbl = __builtin_nan(""); - STL_LOCAL_CONSTEXPR double avr_inf_dbl = __builtin_inf(); - STL_LOCAL_CONSTEXPR long double avr_nan_ldbl = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR long double avr_inf_ldbl = static_cast(__builtin_inf()); - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_quiet_NaN() - { - return std::xfloat_impl::avr_nan_flt; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_signaling_NaN() - { - return 0.0F; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_infinity() - { - return std::xfloat_impl::avr_inf_flt; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_dbl; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_signaling_NaN() - { - return 0.0; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_infinity() - { - return std::xfloat_impl::avr_inf_dbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_ldbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_signaling_NaN() - { - return 0.0L; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_infinity() - { - return std::xfloat_impl::avr_inf_ldbl; - } -} diff --git a/examples/chapter11_07/src/util/STL/impl/avr/avr_hardware_random_device.cpp b/examples/chapter11_07/src/util/STL/impl/avr/avr_hardware_random_device.cpp new file mode 100644 index 000000000..a0f329adb --- /dev/null +++ b/examples/chapter11_07/src/util/STL/impl/avr/avr_hardware_random_device.cpp @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2020 - 2024. +// 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 +#include + +auto my_hardware_random_device_generator(void) -> unsigned int +{ + using timer_type = util::timer; + + const auto t_now = timer_type::get_mark(); + + const auto pseudo_random1 = + math::checksums::crc::crc32_mpeg2 + ( + reinterpret_cast(&t_now), + reinterpret_cast(&t_now) + sizeof(std::uint32_t) + ); + + const auto pseudo_random2 = + math::checksums::crc::crc32_mpeg2 + ( + reinterpret_cast(&t_now) + sizeof(std::uint32_t), + reinterpret_cast(&t_now) + sizeof(std::uint64_t) + ); + + return static_cast(util::make_long(pseudo_random1, pseudo_random2)); +} + +extern "C" unsigned char my_hardware_random_device_entropy(void) +{ + return 1U; +} diff --git a/examples/chapter11_07/src/util/STL/impl/cmath_impl_gamma.cpp b/examples/chapter11_07/src/util/STL/impl/cmath_impl_gamma.cpp index 8edd85ef5..3658e1b28 100644 --- a/examples/chapter11_07/src/util/STL/impl/cmath_impl_gamma.cpp +++ b/examples/chapter11_07/src/util/STL/impl/cmath_impl_gamma.cpp @@ -6,64 +6,64 @@ // #include -#include #include + #include "xcmath_impl.h" -// Here, we compute the tgamma function for std::float32_t. +#if defined(__GNUC__) && defined(__AVR__) +extern "C" float tgammaf(float x); +#endif + +// Here, we compute the tgamma function for float. // This provides an example of a portable special function // calculation using floating-point type definitions having // specified widths from the proposed . -namespace std +namespace xcmath_impl { - namespace xcmath_impl - { - std::float32_t tgamma_inverse_taylor_series (std::float32_t); - std::float32_t tgamma_polynomial_approximation(std::float32_t); - - std::float32_t tgamma_inverse_taylor_series(std::float32_t x) - { - // Implement a small-argument Taylor series for 1 / tgamma(x). - const std::float32_t inverse_series_value - = ((((((( + FLOAT32_C(0.0072189432) - * x - FLOAT32_C(0.0096219715)) - * x - FLOAT32_C(0.0421977346)) - * x + FLOAT32_C(0.1665386114)) - * x - FLOAT32_C(0.0420026350)) - * x - FLOAT32_C(0.6558780715)) - * x + FLOAT32_C(0.5772156649)) - * x + FLOAT32_C(1.0)) - * x; - - return FLOAT32_C(1.0) / inverse_series_value; - } + float tgamma_inverse_taylor_series (float); + float tgamma_polynomial_approximation(float); - std::float32_t tgamma_polynomial_approximation(std::float32_t x) - { - // Implement an order-9 polynomial fit for gamma(1 + x). - const std::float32_t polynomial_approximation_value - = (((((((( - FLOAT32_C(0.0235850272) - * x + FLOAT32_C(0.1405004023)) - * x - FLOAT32_C(0.3860871683)) - * x + FLOAT32_C(0.6721315341)) - * x - FLOAT32_C(0.8649108124)) - * x + FLOAT32_C(0.9539074630)) - * x - FLOAT32_C(0.9035083713)) - * x + FLOAT32_C(0.9887589417)) - * x - FLOAT32_C(0.5772069549)) - * x + FLOAT32_C(0.9999999703); - - // Return the polynomial fit for gamma(x). - // One downward recursion is used here. - return (polynomial_approximation_value / x); - } + float tgamma_inverse_taylor_series(float x) + { + // Implement a small-argument Taylor series for 1 / tgamma(x). + const float inverse_series_value + = ((((((( + 0.0072189432F + * x - 0.0096219715F) + * x - 0.0421977346F) + * x + 0.1665386114F) + * x - 0.0420026350F) + * x - 0.6558780715F) + * x + 0.5772156649F) + * x + 1.0F) + * x; + + return float(1.0F / inverse_series_value); } - std::float32_t tgamma(std::float32_t); + float tgamma_polynomial_approximation(float x) + { + // Implement an order-9 polynomial fit for gamma(1 + x). + const float polynomial_approximation_value + = (((((((( - 0.0235850272F + * x + 0.1405004023F) + * x - 0.3860871683F) + * x + 0.6721315341F) + * x - 0.8649108124F) + * x + 0.9539074630F) + * x - 0.9035083713F) + * x + 0.9887589417F) + * x - 0.5772069549F) + * x + 0.9999999703F; + + // Return the polynomial fit for gamma(x). + // One downward recursion is used here. + return float(polynomial_approximation_value / x); + } } -std::float32_t std::tgamma(std::float32_t x) +extern "C" +float tgammaf(float x) { // Use a positive argument for the Gamma calculation. const bool b_neg = (x < 0); @@ -71,50 +71,50 @@ std::float32_t std::tgamma(std::float32_t x) x = ((!b_neg) ? x : -x); // Check if the argument is pure zero or indistinguishably close to zero. - if(x < (std::numeric_limits::min)()) + if(x < (std::numeric_limits::min)()) { - return std::numeric_limits::quiet_NaN(); + return std::numeric_limits::quiet_NaN(); } // Check if the argument is smaller than epsilon(). - if(x < std::numeric_limits::epsilon()) + if(x < std::numeric_limits::epsilon()) { - using std::xcmath_impl::euler; + using xcmath_impl::euler; - return ((!b_neg) ? (FLOAT32_C(+1.0) / x) - euler() - : (FLOAT32_C(-1.0) / x) - euler()); + return ((!b_neg) ? (+1.0F / x) - euler() + : (-1.0F / x) - euler()); } // Check for overflow. - if(x > FLOAT32_C(35.04)) + if(x > 35.04F) { - return std::numeric_limits::infinity(); + return std::numeric_limits::infinity(); } // Check if the argument is very close to +1 or +2? - if(b_neg == false) + if(!b_neg) { - using std::xcmath_impl::near_integer; + using xcmath_impl::near_integer; const bool is_near_one = near_integer(x, static_cast(1U)); const bool is_near_two = near_integer(x, static_cast(2U)); if(is_near_one || is_near_two) { - return FLOAT32_C(1.0); + return 1.0F; } } // Evaluate the number of recursions needed in order to reach // the range 0 < x < 1, and scale the argument accordingly. - const std::uint_least8_t n_recur = static_cast(std::floor(x)); + const std::uint_least8_t n_recur = static_cast(::floorf(x)); x -= n_recur; // Obtain an approximation of tgamma(x), where x has // perhaps been negated and/or scaled to a lower value. - std::float32_t gamma_value = ((x < FLOAT32_C(0.1)) ? std::xcmath_impl::tgamma_inverse_taylor_series(x) - : std::xcmath_impl::tgamma_polynomial_approximation(x)); + float gamma_value = ((x < 0.1F) ? xcmath_impl::tgamma_inverse_taylor_series(x) + : xcmath_impl::tgamma_polynomial_approximation(x)); // Scale up the result via recursion if necessary. for(std::uint_least8_t k = static_cast(0U); k < n_recur; ++k) @@ -125,16 +125,18 @@ std::float32_t std::tgamma(std::float32_t x) } // Return (and possibly reflect) the result. - if(false == b_neg) + if(!b_neg) { return gamma_value; } else { - using std::xcmath_impl::pi; + using xcmath_impl::pi; + + using std::sin; - const std::float32_t sin_pi_x = std::sin(pi() * x); + const float sin_pi_x = sin(pi() * x); - return -pi() / ((x * gamma_value) * sin_pi_x); + return -pi() / ((x * gamma_value) * sin_pi_x); } } diff --git a/examples/chapter11_07/src/util/STL/impl/cmath_impl_hyperbolic.cpp b/examples/chapter11_07/src/util/STL/impl/cmath_impl_hyperbolic.cpp index 463879188..715bcab0b 100644 --- a/examples/chapter11_07/src/util/STL/impl/cmath_impl_hyperbolic.cpp +++ b/examples/chapter11_07/src/util/STL/impl/cmath_impl_hyperbolic.cpp @@ -6,12 +6,17 @@ // #include -#include #include #include "xcmath_impl.h" +#if defined(__GNUC__) && defined(__AVR__) +extern "C" float asinhf(float x); +extern "C" float acoshf(float x); +extern "C" float atanhf(float x); +#endif + // Here, we implement naive computations of the inverse hyperbolic -// trigonometric functions asinh, acosh, and atanh for std::float32_t. +// trigonometric functions asinh, acosh, and atanh for float. // The inverse hyperbolic trigonometric functions are represented // in terms of logarithmic functions. @@ -19,65 +24,71 @@ // elementary transcendental functions using floating-point typedefs // having specified widths. -namespace std -{ - std::float32_t asinh(std::float32_t); - std::float32_t acosh(std::float32_t); - std::float32_t atanh(std::float32_t); -} - -std::float32_t std::asinh(std::float32_t x) +extern "C" +float asinhf(float x) { // Implement a naive hyperbolic arc-sine function. - return std::log(x + std::sqrt((x * x) + FLOAT32_C(1.0))); + + using std::log; + using std::sqrt; + + return log(x + sqrt((x * x) + 1.0F)); } -std::float32_t std::acosh(std::float32_t x) +extern "C" +float acoshf(float x) { - const std::float32_t x_minus_one = x - FLOAT32_C(1.0); + const float x_minus_one = x - 1.0F; - if(x_minus_one < -std::numeric_limits::epsilon()) + if(x_minus_one < -std::numeric_limits::epsilon()) { - return std::numeric_limits::quiet_NaN(); + return std::numeric_limits::quiet_NaN(); } - else if(x_minus_one < std::numeric_limits::epsilon()) + else if(x_minus_one < std::numeric_limits::epsilon()) { - return FLOAT32_C(1.0); + return 1.0F; } else { // Implement a naive hyperbolic arc-cosine function. - const std::float32_t xp = (x + FLOAT32_C(1.0)); - const std::float32_t xm = (x - FLOAT32_C(1.0)); - return std::log(x + std::sqrt(xm * xp)); + using std::log; + using std::sqrt; + + const float xp = (x + 1.0F); + const float xm = (x - 1.0F); + + return log(x + sqrt(xm * xp)); } } -std::float32_t std::atanh(std::float32_t x) +extern "C" +float atanhf(float x) { - const bool is_neg = (x < FLOAT32_C(0.0)); + const bool is_neg = (x < 0.0F); - const std::float32_t xx = ((!is_neg) ? x : -x); + const float xx = ((!is_neg) ? x : -x); - if(xx > FLOAT32_C(1.0)) + if(xx > 1.0F) { - return std::numeric_limits::quiet_NaN(); + return std::numeric_limits::quiet_NaN(); } - std::float32_t result; + float result; - if(xx < FLOAT32_C(1.0)) + if(xx < 1.0F) { // Implement a naive hyperbolic arc-tangent function. - const std::float32_t xp = (xx + FLOAT32_C(1.0)); - const std::float32_t xm = (FLOAT32_C(1.0) - xx); + const float xp = (xx + 1.0F); + const float xm = (1.0F - xx); + + using std::log; - result = (std::log(xp) - std::log(xm)) / FLOAT32_C(2.0); + result = (float) (log(xp) - log(xm)) / 2.0F; } else { - result = std::numeric_limits::infinity(); + result = std::numeric_limits::infinity(); } return ((!is_neg) ? result : -result); diff --git a/examples/chapter11_07/src/util/STL/impl/ptr_traits.h b/examples/chapter11_07/src/util/STL/impl/ptr_traits.h new file mode 100644 index 000000000..eb3ad05fa --- /dev/null +++ b/examples/chapter11_07/src/util/STL/impl/ptr_traits.h @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021 - 2022. +// 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) +// + +// Pointer Traits -*- C++ -*- + +// Copyright (C) 2011-2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +#ifndef PTR_TRAITS_2021_01_26_H_ + #define PTR_TRAITS_2021_01_26_H_ + + #include + + namespace std + { + template + using __void_t = void; + + // Implementation of the detection idiom (negative case). + template class _Op, typename... _Args> + struct __detector + { + using value_t = false_type; + using type = _Default; + }; + + // Implementation of the detection idiom (positive case). + template class _Op, + typename... _Args> + struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> + { + using value_t = true_type; + using type = _Op<_Args...>; + }; + + // Detect whether _Op<_Args...> is a valid type, use _Default if not. + template class _Op, typename... _Args> + using __detected_or = __detector<_Default, void, _Op, _Args...>; + + // _Op<_Args...> if that is a valid type, otherwise _Default. + template class _Op, typename... _Args> + using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; + + class __undefined; + + // Given Template return T, otherwise invalid. + template + struct __get_first_arg + { using type = __undefined; }; + + template class _Template, + typename _Tp, + typename... _Types> + struct __get_first_arg<_Template<_Tp, _Types...>> + { using type = _Tp; }; + + template + using __get_first_arg_t = typename __get_first_arg<_Tp>::type; + + // Given Template and U return Template, otherwise invalid. + template + struct __replace_first_arg { }; + + template class _Template, + typename _Up, + typename _Tp, typename... _Types> + struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> + { using type = _Template<_Up, _Types...>; }; + + template + using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type; + + template + using __make_not_void = typename conditional::value, __undefined, _Tp>::type; + + template + struct pointer_traits + { + private: + template + using __element_type = typename _Tp::element_type; + + template + using __difference_type = typename _Tp::difference_type; + + template + struct __rebind : __replace_first_arg<_Tp, _Up> { }; + + template + struct __rebind<_Tp, _Up, __void_t>> + { using type = typename _Tp::template rebind<_Up>; }; + + public: + using pointer = _Ptr; + using element_type = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>; + using difference_type = __detected_or_t; + + template + using rebind = typename __rebind<_Ptr, _Up>::type; + + static _Ptr pointer_to(__make_not_void& __e) + { return _Ptr::pointer_to(__e); } + + static_assert(!is_same::value, + "pointer type defines element_type or is like SomePointer"); + }; + + template + struct pointer_traits<_Tp*> + { + typedef _Tp* pointer; + typedef _Tp element_type; + typedef ptrdiff_t difference_type; + + template + using rebind = _Up*; + + static constexpr pointer pointer_to(__make_not_void& __r) + { return std::addressof(__r); } + }; + + // Convenience alias for rebinding pointers. + template + using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>; + + template + constexpr _Tp* __to_address(_Tp* __ptr) + { + return __ptr; + } + + #if __cplusplus <= 201703L + template + constexpr typename std::pointer_traits<_Ptr>::element_type* __to_address(const _Ptr& __ptr) + { return std::__to_address(__ptr.operator->()); } + #else + template + constexpr auto __to_address(const _Ptr& __ptr) -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr)) + { return std::pointer_traits<_Ptr>::to_address(__ptr); } + + template + constexpr auto __to_address(const _Ptr& __ptr, _None...) + { + return std::__to_address(__ptr.operator->()); + } + + template + constexpr _Tp* + to_address(_Tp* __ptr) + { return std::__to_address(__ptr); } + + template + constexpr auto + to_address(const _Ptr& __ptr) + { return std::__to_address(__ptr); } + + #endif // C++2a + } + +#endif // PTR_TRAITS_2021_01_26_H_ diff --git a/examples/chapter11_07/src/util/STL/impl/rl78/rl78_float_limits.cpp b/examples/chapter11_07/src/util/STL/impl/rl78/rl78_float_limits.cpp deleted file mode 100644 index 5a7597274..000000000 --- a/examples/chapter11_07/src/util/STL/impl/rl78/rl78_float_limits.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. -// 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 - -namespace std -{ - namespace xfloat_impl - { - // Use some GCC internal stuff here. - STL_LOCAL_CONSTEXPR float avr_nan_flt = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR float avr_inf_flt = static_cast(__builtin_inf()); - STL_LOCAL_CONSTEXPR double avr_nan_dbl = __builtin_nan(""); - STL_LOCAL_CONSTEXPR double avr_inf_dbl = __builtin_inf(); - STL_LOCAL_CONSTEXPR long double avr_nan_ldbl = static_cast(__builtin_nan("")); - STL_LOCAL_CONSTEXPR long double avr_inf_ldbl = static_cast(__builtin_inf()); - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_quiet_NaN() - { - return std::xfloat_impl::avr_nan_flt; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_signaling_NaN() - { - return 0.0F; - } - - float numeric_limits_details::my_value_that_needs_to_be_provided_flt_infinity() - { - return std::xfloat_impl::avr_inf_flt; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_dbl; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_signaling_NaN() - { - return 0.0; - } - - double numeric_limits_details::my_value_that_needs_to_be_provided_dbl_infinity() - { - return std::xfloat_impl::avr_inf_dbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_quiet_NaN() - { - return std::xfloat_impl::avr_nan_ldbl; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_signaling_NaN() - { - return 0.0L; - } - - long double numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_infinity() - { - return std::xfloat_impl::avr_inf_ldbl; - } -} diff --git a/examples/chapter11_07/src/util/STL/impl/stl_local_constexpr.h b/examples/chapter11_07/src/util/STL/impl/stl_local_constexpr.h index ec4112078..b010f2cfa 100644 --- a/examples/chapter11_07/src/util/STL/impl/stl_local_constexpr.h +++ b/examples/chapter11_07/src/util/STL/impl/stl_local_constexpr.h @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014 - 2022. // 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) @@ -8,7 +8,27 @@ #ifndef STL_LOCAL_CONSTEXPR_2014_12_04_H_ #define STL_LOCAL_CONSTEXPR_2014_12_04_H_ - #if defined(__GNUC__) + #if (defined(__cplusplus) && (__cplusplus >= 201402L)) + #if defined(__AVR__) && (!defined(__GNUC__) || (defined(__GNUC__) && (__GNUC__ > 7))) + #define STL_LOCAL_CONSTEXPR_ALGORITHMS constexpr + #elif (defined(__cpp_lib_constexpr_algorithms) && (__cpp_lib_constexpr_algorithms>=201806)) + #if defined(__clang__) + #if (__clang_major__ > 9) + #define STL_LOCAL_CONSTEXPR_ALGORITHMS constexpr + #else + #define STL_LOCAL_CONSTEXPR_ALGORITHMS + #endif + #else + #define STL_LOCAL_CONSTEXPR_ALGORITHMS constexpr + #endif + #else + #define STL_LOCAL_CONSTEXPR_ALGORITHMS + #endif + #else + #define STL_LOCAL_CONSTEXPR_ALGORITHMS + #endif + + #if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) #define STL_LOCAL_CONSTEXPR constexpr #else #define STL_LOCAL_CONSTEXPR const diff --git a/examples/chapter11_07/src/util/STL/impl/stl_local_noexcept.h b/examples/chapter11_07/src/util/STL/impl/stl_local_noexcept.h index 2f2c95fd2..6ea9125da 100644 --- a/examples/chapter11_07/src/util/STL/impl/stl_local_noexcept.h +++ b/examples/chapter11_07/src/util/STL/impl/stl_local_noexcept.h @@ -10,6 +10,8 @@ #if defined(_MSC_VER) #define STL_LOCAL_NOEXCEPT throw() + #elif defined(__IAR_SYSTEMS_ICC__) + #define STL_LOCAL_NOEXCEPT #else #define STL_LOCAL_NOEXCEPT noexcept #endif diff --git a/examples/chapter11_07/src/util/STL/impl/xcmath_impl.h b/examples/chapter11_07/src/util/STL/impl/xcmath_impl.h index f0d9b4f73..1120d94ff 100644 --- a/examples/chapter11_07/src/util/STL/impl/xcmath_impl.h +++ b/examples/chapter11_07/src/util/STL/impl/xcmath_impl.h @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -12,7 +12,7 @@ #include #include - namespace std { namespace xcmath_impl { + namespace xcmath_impl { template bool near_integer(const float_type& x, const std::uint_least8_t n) @@ -27,22 +27,23 @@ } template - const float_type pi() + constexpr float_type pi() { - return static_cast(FLOATMAX_C(3.1415926535897932384626433832795028841972)); + return static_cast(3.1415926535897932384626433832795028841972L); } template - const float_type ln_two() + constexpr float_type ln_two() { - return static_cast(FLOATMAX_C(0.6931471805599453094172321214581765680755)); + return static_cast(0.6931471805599453094172321214581765680755L); } - template - const float_type euler() - { - return static_cast(FLOATMAX_C(0.5772156649015328606065120900824024310422)); - } - } } // namespace std::xcmath_impl + template + constexpr float_type euler() + { + return static_cast(0.5772156649015328606065120900824024310422L); + } + + } // namespace xcmath_impl #endif // XCMATH_IMPL_2014_01_11_H_ diff --git a/examples/chapter11_07/src/util/STL/iterator b/examples/chapter11_07/src/util/STL/iterator index 7d65caff8..b21b81899 100644 --- a/examples/chapter11_07/src/util/STL/iterator +++ b/examples/chapter11_07/src/util/STL/iterator @@ -8,6 +8,8 @@ #ifndef ITERATOR_2010_02_23_ #define ITERATOR_2010_02_23_ + #include + #include // Implement some of for compilers that do not yet support it. @@ -52,10 +54,7 @@ typedef const value_type& reference; typedef random_access_iterator_tag iterator_category; }; - } - namespace std - { template @@ -86,56 +85,57 @@ typedef typename iterator_traits::reference reference; typedef typename iterator_traits::iterator_category iterator_category; - reverse_iterator() { } + constexpr reverse_iterator() = default; - explicit reverse_iterator(iterator_type x) : current(x) { } + explicit constexpr reverse_iterator(iterator_type x) : current(x) { } template - reverse_iterator(const reverse_iterator& u) : current(u.current) { } + constexpr reverse_iterator(const reverse_iterator& u) : current(u.current) { } - iterator_type base() const { return current; } + constexpr iterator_type base() const { return current; } - reference operator*() const { iterator_type tmp = current; return *--tmp; } - pointer operator->() const { return &(operator*()); } + STL_LOCAL_CONSTEXPR_ALGORITHMS reference operator* () const { iterator_type tmp = current; return *--tmp; } + constexpr pointer operator->() const { return &(operator*()); } - reverse_iterator& operator++() { --current; return *this; } - reverse_iterator& operator--() { ++current; return *this; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator& operator++() { --current; return *this; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator& operator--() { ++current; return *this; } - reverse_iterator operator++(int) { reverse_iterator tmp = *this; --current; return tmp; } - reverse_iterator operator--(int) { reverse_iterator tmp = *this; ++current; return tmp; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator operator++(int) { reverse_iterator tmp = *this; --current; return tmp; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator operator--(int) { reverse_iterator tmp = *this; ++current; return tmp; } - reverse_iterator operator+(typename reverse_iterator::difference_type n) const { return reverse_iterator(current - n); } - reverse_iterator operator-(typename reverse_iterator::difference_type n) const { return reverse_iterator(current + n); } + constexpr reverse_iterator operator+(typename reverse_iterator::difference_type n) const { return reverse_iterator(current - n); } + constexpr reverse_iterator operator-(typename reverse_iterator::difference_type n) const { return reverse_iterator(current + n); } - reverse_iterator& operator+=(typename reverse_iterator::difference_type n) { current -= n; return *this; } - reverse_iterator& operator-=(typename reverse_iterator::difference_type n) { current += n; return *this; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator& operator+=(typename reverse_iterator::difference_type n) { current -= n; return *this; } + STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator& operator-=(typename reverse_iterator::difference_type n) { current += n; return *this; } - reference operator[](typename reverse_iterator::difference_type n) const { return current[-n - 1]; } + constexpr reference operator[](typename reverse_iterator::difference_type n) const { return current[-n - 1]; } private: iterator_type current; - friend inline bool operator< (const reverse_iterator& x, const reverse_iterator& y) { return (x.current > y.current); } - friend inline bool operator<=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current >= y.current); } - friend inline bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return (x.current == y.current); } - friend inline bool operator!=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current != y.current); } - friend inline bool operator>=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current <= y.current); } - friend inline bool operator> (const reverse_iterator& x, const reverse_iterator& y) { return (x.current < y.current); } + friend inline constexpr bool operator< (const reverse_iterator& x, const reverse_iterator& y) { return (x.current > y.current); } + friend inline constexpr bool operator<=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current >= y.current); } + friend inline constexpr bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return (x.current == y.current); } + friend inline constexpr bool operator!=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current != y.current); } + friend inline constexpr bool operator>=(const reverse_iterator& x, const reverse_iterator& y) { return (x.current <= y.current); } + friend inline constexpr bool operator> (const reverse_iterator& x, const reverse_iterator& y) { return (x.current < y.current); } - friend inline typename reverse_iterator::difference_type operator-(const reverse_iterator& x, - const reverse_iterator& y) + friend inline constexpr typename reverse_iterator::difference_type operator-(const reverse_iterator& x, + const reverse_iterator& y) { return (y.current - x.current); } - friend inline reverse_iterator operator+(typename reverse_iterator::difference_type n, - const reverse_iterator& x) + friend inline constexpr reverse_iterator operator+(typename reverse_iterator::difference_type n, + const reverse_iterator& x) { return reverse_iterator(x.current - n); } }; template + STL_LOCAL_CONSTEXPR_ALGORITHMS typename iterator_traits::difference_type distance(input_iterator first, input_iterator last) { @@ -155,6 +155,7 @@ template + STL_LOCAL_CONSTEXPR_ALGORITHMS void advance(input_iterator& it, distance_type n) { for(distance_type i = distance_type(0); i != n; ++i, ++it) @@ -164,31 +165,31 @@ } // See ISO/IEC 14882:2011, near the end of Section 24.3. - template inline auto begin( container_type& c) -> decltype(c.begin()) { return c.begin(); } - template inline auto begin(const container_type& c) -> decltype(c.begin()) { return c.begin(); } - template inline auto cbegin(const container_type& c) -> decltype(c.cbegin()) { return c.cbegin(); } - template inline auto end ( container_type& c) -> decltype(c.end()) { return c.end(); } - template inline auto end (const container_type& c) -> decltype(c.end()) { return c.end(); } - template inline auto cend (const container_type& c) -> decltype(c.cend()) { return c.cend(); } - - template inline auto rbegin( container_type& c) -> decltype(c.rbegin()) { return c.rbegin(); } - template inline auto rbegin(const container_type& c) -> decltype(c.rbegin()) { return c.rbegin(); } - template inline auto crbegin(const container_type& c) -> decltype(c.crbegin()) { return c.crbegin(); } - template inline auto rend ( container_type& c) -> decltype(c.rend()) { return c.rend(); } - template inline auto rend (const container_type& c) -> decltype(c.rend()) { return c.rend(); } - template inline auto crend (const container_type& c) -> decltype(c.crend()) { return c.crend(); } - - template inline value_type* begin (value_type(&c_array)[N]) { return &c_array[0U]; } - template inline value_type* end (value_type(&c_array)[N]) { return &c_array[N]; } - - template inline const value_type* cbegin (value_type(&c_array)[N]) { return &c_array[0U]; } - template inline const value_type* cend (value_type(&c_array)[N]) { return &c_array[N]; } - - template inline value_type* rbegin (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[N]); } - template inline value_type* rend (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[0U]); } - - template inline const value_type* crbegin(value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[N]); } - template inline const value_type* crend (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[0U]); } + template inline constexpr auto begin( container_type& c) -> decltype(c.begin()) { return c.begin(); } + template inline constexpr auto begin(const container_type& c) -> decltype(c.begin()) { return c.begin(); } + template inline constexpr auto cbegin(const container_type& c) -> decltype(c.cbegin()) { return c.cbegin(); } + template inline constexpr auto end ( container_type& c) -> decltype(c.end()) { return c.end(); } + template inline constexpr auto end (const container_type& c) -> decltype(c.end()) { return c.end(); } + template inline constexpr auto cend (const container_type& c) -> decltype(c.cend()) { return c.cend(); } + + template inline constexpr auto rbegin( container_type& c) -> decltype(c.rbegin()) { return c.rbegin(); } + template inline constexpr auto rbegin(const container_type& c) -> decltype(c.rbegin()) { return c.rbegin(); } + template inline constexpr auto crbegin(const container_type& c) -> decltype(c.crbegin()) { return c.crbegin(); } + template inline constexpr auto rend ( container_type& c) -> decltype(c.rend()) { return c.rend(); } + template inline constexpr auto rend (const container_type& c) -> decltype(c.rend()) { return c.rend(); } + template inline constexpr auto crend (const container_type& c) -> decltype(c.crend()) { return c.crend(); } + + template inline constexpr value_type* begin (value_type(&c_array)[N]) { return &c_array[0U]; } + template inline constexpr value_type* end (value_type(&c_array)[N]) { return &c_array[N]; } + + template inline const constexpr value_type* cbegin (value_type(&c_array)[N]) { return &c_array[0U]; } + template inline const constexpr value_type* cend (value_type(&c_array)[N]) { return &c_array[N]; } + + template inline constexpr value_type* rbegin (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[N]); } + template inline constexpr value_type* rend (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[0U]); } + + template inline const constexpr value_type* crbegin(value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[N]); } + template inline const constexpr value_type* crend (value_type(&c_array)[N]) { return std::reverse_iterator(&c_array[0U]); } } #endif // ITERATOR_2010_02_23_ diff --git a/examples/chapter11_07/src/util/STL/limits b/examples/chapter11_07/src/util/STL/limits index 367a2fb1e..15bf177a3 100644 --- a/examples/chapter11_07/src/util/STL/limits +++ b/examples/chapter11_07/src/util/STL/limits @@ -19,6 +19,9 @@ // The implementation was partly inspired by some concepts in GCC's // implementation of . + #if defined(__GNUC__) && defined(__XTENSA__) + extern "C++" { + #endif namespace std { #define CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS true @@ -52,25 +55,52 @@ class numeric_limits_details { private: - static const long long my_long_long_max = 0x7FFFFFFFFFFFFFFFLL; + static constexpr long long my_long_long_max = 0x7FFFFFFFFFFFFFFFLL; // The following values for float, double, and long double are provided // in a separate file that is dependent on the AVR architecture. - static float my_value_that_needs_to_be_provided_flt_infinity(); - static float my_value_that_needs_to_be_provided_flt_quiet_NaN(); - static float my_value_that_needs_to_be_provided_flt_signaling_NaN(); - static float my_value_that_needs_to_be_provided_flt_denorm_min(); - - static double my_value_that_needs_to_be_provided_dbl_infinity(); - static double my_value_that_needs_to_be_provided_dbl_quiet_NaN(); - static double my_value_that_needs_to_be_provided_dbl_signaling_NaN(); - static double my_value_that_needs_to_be_provided_dbl_denorm_min(); - - static long double my_value_that_needs_to_be_provided_ldbl_infinity(); - static long double my_value_that_needs_to_be_provided_ldbl_quiet_NaN(); - static long double my_value_that_needs_to_be_provided_ldbl_signaling_NaN(); - static long double my_value_that_needs_to_be_provided_ldbl_denorm_min(); + #if defined(__GNUC__) + static constexpr float my_value_that_needs_to_be_provided_flt_infinity() { return __builtin_inff(); } + static constexpr float my_value_that_needs_to_be_provided_flt_quiet_NaN() { return __builtin_nanf(""); } + static constexpr float my_value_that_needs_to_be_provided_flt_signaling_NaN() { return __builtin_nanf(""); } + #endif + #if defined(__IAR_SYSTEMS_ICC__) + static constexpr float my_value_that_needs_to_be_provided_flt_infinity() { return 0.Infinity; } + static constexpr float my_value_that_needs_to_be_provided_flt_quiet_NaN() { return 0.NaN; } + static constexpr float my_value_that_needs_to_be_provided_flt_signaling_NaN() { return 0.NaN; } + #endif + static constexpr float my_value_that_needs_to_be_provided_flt_denorm_min() { return FLT_MIN; } + + #if defined(__GNUC__) + #if defined(__AVR__) && (__SIZEOF_DOUBLE__ == 8) + static constexpr double my_value_that_needs_to_be_provided_dbl_infinity() { return __builtin_infl(); } + static constexpr double my_value_that_needs_to_be_provided_dbl_quiet_NaN() { return __builtin_nanl(""); } + static constexpr double my_value_that_needs_to_be_provided_dbl_signaling_NaN() { return __builtin_nanl(""); } + #else + static constexpr double my_value_that_needs_to_be_provided_dbl_infinity() { return __builtin_inf(); } + static constexpr double my_value_that_needs_to_be_provided_dbl_quiet_NaN() { return __builtin_nan(""); } + static constexpr double my_value_that_needs_to_be_provided_dbl_signaling_NaN() { return __builtin_nan(""); } + #endif + #endif + #if defined(__IAR_SYSTEMS_ICC__) + static constexpr double my_value_that_needs_to_be_provided_dbl_infinity() { return 0.Infinity; } + static constexpr double my_value_that_needs_to_be_provided_dbl_quiet_NaN() { return 0.NaN; } + static constexpr double my_value_that_needs_to_be_provided_dbl_signaling_NaN() { return 0.NaN; } + #endif + static constexpr double my_value_that_needs_to_be_provided_dbl_denorm_min() { return DBL_MIN; } + + #if defined(__GNUC__) + static constexpr long double my_value_that_needs_to_be_provided_ldbl_infinity() { return __builtin_infl(); } + static constexpr long double my_value_that_needs_to_be_provided_ldbl_quiet_NaN() { return __builtin_nanl(""); } + static constexpr long double my_value_that_needs_to_be_provided_ldbl_signaling_NaN() { return __builtin_nanl(""); } + #endif + #if defined(__IAR_SYSTEMS_ICC__) + static constexpr long double my_value_that_needs_to_be_provided_ldbl_infinity() { return 0.Infinity; } + static constexpr long double my_value_that_needs_to_be_provided_ldbl_quiet_NaN() { return 0.NaN; } + static constexpr long double my_value_that_needs_to_be_provided_ldbl_signaling_NaN() { return 0.NaN; } + #endif + static constexpr long double my_value_that_needs_to_be_provided_ldbl_denorm_min() { return LDBL_MIN; } template friend class numeric_limits; @@ -80,39 +110,39 @@ class numeric_limits { public: - static const bool is_specialized = false; - static const int digits = 0; - static const int digits10 = 0; - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = 0; - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - static const bool is_iec559 = false; - static const bool is_bounded = false; - static const bool is_modulo = false; - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; - - static T (min)() throw() { return static_cast(0); } - static T (max)() throw() { return static_cast(0); } - static T lowest() throw() { return static_cast(0); } - static T epsilon() throw() { return static_cast(0); } - static T round_error() throw() { return static_cast(0); } - static T infinity() throw() { return static_cast(0); } - static T quiet_NaN() throw() { return static_cast(0); } - static T signaling_NaN() throw() { return static_cast(0); } - static T denorm_min() throw() { return static_cast(0); } + static constexpr bool is_specialized = false; + static constexpr int digits = 0; + static constexpr int digits10 = 0; + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 0; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = false; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; + + static constexpr T (min)() throw() { return static_cast(0); } + static constexpr T (max)() throw() { return static_cast(0); } + static constexpr T lowest() throw() { return static_cast(0); } + static constexpr T epsilon() throw() { return static_cast(0); } + static constexpr T round_error() throw() { return static_cast(0); } + static constexpr T infinity() throw() { return static_cast(0); } + static constexpr T quiet_NaN() throw() { return static_cast(0); } + static constexpr T signaling_NaN() throw() { return static_cast(0); } + static constexpr T denorm_min() throw() { return static_cast(0); } }; // Specialization for bool. @@ -120,46 +150,46 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static bool (min)() throw() { return false; } - static bool (max)() throw() { return true; } - static bool lowest() throw() { return (min)(); } - - static const int digits = 1; - static const int digits10 = 0; - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static bool epsilon() throw() { return false; } - static bool round_error() throw() { return false; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static bool infinity() throw() { return false; } - static bool quiet_NaN() throw() { return false; } - static bool signaling_NaN() throw() { return false; } - static bool denorm_min() throw() { return false; } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = false; - - static const bool traps = true; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr bool (min)() throw() { return false; } + static constexpr bool (max)() throw() { return true; } + static constexpr bool lowest() throw() { return (min)(); } + + static constexpr int digits = 1; + static constexpr int digits10 = 0; + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr bool epsilon() throw() { return false; } + static constexpr bool round_error() throw() { return false; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr bool infinity() throw() { return false; } + static constexpr bool quiet_NaN() throw() { return false; } + static constexpr bool signaling_NaN() throw() { return false; } + static constexpr bool denorm_min() throw() { return false; } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + + static constexpr bool traps = true; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for char. @@ -167,44 +197,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static char (min)() throw() { return CHAR_MIN; } - static char (max)() throw() { return CHAR_MAX; } - static char lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(char); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(char); - static const int max_digits10 = 0; - static const bool is_signed = CONCEPT_FROM_GLIBCXX_IS_SIGNED(char); - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static char epsilon() throw() { return 0; } - static char round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static char infinity() throw() { return char(); } - static char quiet_NaN() throw() { return char(); } - static char signaling_NaN() throw() { return char(); } - static char denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr char (min)() throw() { return CHAR_MIN; } + static constexpr char (max)() throw() { return CHAR_MAX; } + static constexpr char lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(char); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(char); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = CONCEPT_FROM_GLIBCXX_IS_SIGNED(char); + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr char epsilon() throw() { return 0; } + static constexpr char round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr char infinity() throw() { return char(); } + static constexpr char quiet_NaN() throw() { return char(); } + static constexpr char signaling_NaN() throw() { return char(); } + static constexpr char denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for signed char. @@ -212,45 +242,45 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static signed char (min)() throw() { return -SCHAR_MAX - 1; } - static signed char (max)() throw() { return SCHAR_MAX; } - static signed char lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(signed char); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(signed char); - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static signed char epsilon() throw() { return 0; } - static signed char round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static signed char infinity() throw() { return static_cast(0); } - static signed char quiet_NaN() throw() { return static_cast(0); } - static signed char signaling_NaN() throw() { return static_cast(0); } - static signed char denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr signed char (min)() throw() { return -SCHAR_MAX - 1; } + static constexpr signed char (max)() throw() { return SCHAR_MAX; } + static constexpr signed char lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(signed char); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(signed char); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr signed char epsilon() throw() { return 0; } + static constexpr signed char round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr signed char infinity() throw() { return static_cast(0); } + static constexpr signed char quiet_NaN() throw() { return static_cast(0); } + static constexpr signed char signaling_NaN() throw() { return static_cast(0); } + static constexpr signed char denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for unsigned char. @@ -258,46 +288,46 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static unsigned char (min)() throw() { return 0; } - static unsigned char (max)() throw() { return (SCHAR_MAX * 2U) + 1; } - static unsigned char lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned char); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned char); - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static unsigned char epsilon() throw() { return 0; } - static unsigned char round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static unsigned char infinity() throw() { return static_cast(0); } - static unsigned char quiet_NaN() throw() { return static_cast(0); } - static unsigned char signaling_NaN() throw() { return static_cast(0); } - static unsigned char denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr unsigned char (min)() throw() { return 0; } + static constexpr unsigned char (max)() throw() { return (SCHAR_MAX * 2U) + 1; } + static constexpr unsigned char lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned char); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned char); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr unsigned char epsilon() throw() { return 0; } + static constexpr unsigned char round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr unsigned char infinity() throw() { return static_cast(0); } + static constexpr unsigned char quiet_NaN() throw() { return static_cast(0); } + static constexpr unsigned char signaling_NaN() throw() { return static_cast(0); } + static constexpr unsigned char denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; @@ -306,45 +336,45 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static short (min)() throw() { return -SHRT_MAX - 1; } - static short (max)() throw() { return SHRT_MAX; } - static short lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(short); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(short); - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static short epsilon() throw() { return 0; } - static short round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static short infinity() throw() { return short(); } - static short quiet_NaN() throw() { return short(); } - static short signaling_NaN() throw() { return short(); } - static short denorm_min() throw() { return short(); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr short (min)() throw() { return -SHRT_MAX - 1; } + static constexpr short (max)() throw() { return SHRT_MAX; } + static constexpr short lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(short); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(short); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr short epsilon() throw() { return 0; } + static constexpr short round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr short infinity() throw() { return short(); } + static constexpr short quiet_NaN() throw() { return short(); } + static constexpr short signaling_NaN() throw() { return short(); } + static constexpr short denorm_min() throw() { return short(); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for unsigned short. @@ -352,44 +382,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static unsigned short (min)() throw() { return 0; } - static unsigned short (max)() throw() { return (SHRT_MAX * 2U) + 1; } - static unsigned short lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned short); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned short); - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static unsigned short epsilon() throw() { return 0; } - static unsigned short round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static unsigned short infinity() throw() { return static_cast(0); } - static unsigned short quiet_NaN() throw() { return static_cast(0); } - static unsigned short signaling_NaN() throw() { return static_cast(0); } - static unsigned short denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr unsigned short (min)() throw() { return 0; } + static constexpr unsigned short (max)() throw() { return (SHRT_MAX * 2U) + 1; } + static constexpr unsigned short lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned short); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned short); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr unsigned short epsilon() throw() { return 0; } + static constexpr unsigned short round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr unsigned short infinity() throw() { return static_cast(0); } + static constexpr unsigned short quiet_NaN() throw() { return static_cast(0); } + static constexpr unsigned short signaling_NaN() throw() { return static_cast(0); } + static constexpr unsigned short denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for int. @@ -397,44 +427,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static int (min)() throw() { return -INT_MAX - 1; } - static int (max)() throw() { return INT_MAX; } - static int lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(int); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(int); - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static int epsilon() throw() { return 0; } - static int round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static int infinity() throw() { return static_cast(0); } - static int quiet_NaN() throw() { return static_cast(0); } - static int signaling_NaN() throw() { return static_cast(0); } - static int denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr int (min)() throw() { return -INT_MAX - 1; } + static constexpr int (max)() throw() { return INT_MAX; } + static constexpr int lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(int); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(int); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr int epsilon() throw() { return 0; } + static constexpr int round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr int infinity() throw() { return static_cast(0); } + static constexpr int quiet_NaN() throw() { return static_cast(0); } + static constexpr int signaling_NaN() throw() { return static_cast(0); } + static constexpr int denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for unsigned int. @@ -442,45 +472,45 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static unsigned int (min)() throw() { return 0; } - static unsigned int (max)() throw() { return (INT_MAX * 2U) + 1; } - static unsigned int lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned int); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned int); - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static unsigned int epsilon() throw() { return 0; } - static unsigned int round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static unsigned int infinity() throw() { return static_cast(0); } - static unsigned int quiet_NaN() throw() { return static_cast(0); } - static unsigned int signaling_NaN() throw() { return static_cast(0); } - static unsigned int denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr unsigned int (min)() throw() { return 0; } + static constexpr unsigned int (max)() throw() { return (INT_MAX * 2U) + 1; } + static constexpr unsigned int lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned int); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned int); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr unsigned int epsilon() throw() { return 0; } + static constexpr unsigned int round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr unsigned int infinity() throw() { return static_cast(0); } + static constexpr unsigned int quiet_NaN() throw() { return static_cast(0); } + static constexpr unsigned int signaling_NaN() throw() { return static_cast(0); } + static constexpr unsigned int denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for long. @@ -488,44 +518,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static long (min)() throw() { return -LONG_MAX - 1; } - static long (max)() throw() { return LONG_MAX; } - static long lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(long); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(long); - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static long epsilon() throw() { return 0; } - static long round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static long infinity() throw() { return static_cast(0); } - static long quiet_NaN() throw() { return static_cast(0); } - static long signaling_NaN() throw() { return static_cast(0); } - static long denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr long (min)() throw() { return -LONG_MAX - 1; } + static constexpr long (max)() throw() { return LONG_MAX; } + static constexpr long lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(long); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(long); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr long epsilon() throw() { return 0; } + static constexpr long round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr long infinity() throw() { return static_cast(0); } + static constexpr long quiet_NaN() throw() { return static_cast(0); } + static constexpr long signaling_NaN() throw() { return static_cast(0); } + static constexpr long denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for unsigned long. @@ -533,44 +563,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static unsigned long (min)() throw() { return 0; } - static unsigned long (max)() throw() { return (LONG_MAX * 2UL) + 1; } - static unsigned long lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned long); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned long); - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static unsigned long epsilon() throw() { return 0; } - static unsigned long round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static unsigned long infinity() throw() { return static_cast(0); } - static unsigned long quiet_NaN() throw() { return static_cast(0); } - static unsigned long signaling_NaN() throw() { return static_cast(0); } - static unsigned long denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr unsigned long (min)() throw() { return 0; } + static constexpr unsigned long (max)() throw() { return (LONG_MAX * 2UL) + 1; } + static constexpr unsigned long lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned long); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned long); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr unsigned long epsilon() throw() { return 0; } + static constexpr unsigned long round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr unsigned long infinity() throw() { return static_cast(0); } + static constexpr unsigned long quiet_NaN() throw() { return static_cast(0); } + static constexpr unsigned long signaling_NaN() throw() { return static_cast(0); } + static constexpr unsigned long denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for long long. @@ -578,44 +608,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static long long (min)() throw() { return -numeric_limits_details::my_long_long_max - 1; } - static long long (max)() throw() { return numeric_limits_details::my_long_long_max; } - static long long lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(long long); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(long long); - static const int max_digits10 = 0; - static const bool is_signed = true; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static long long epsilon() throw() { return 0; } - static long long round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static long long infinity() throw() { return static_cast(0); } - static long long quiet_NaN() throw() { return static_cast(0); } - static long long signaling_NaN() throw() { return static_cast(0); } - static long long denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr long long (min)() throw() { return -numeric_limits_details::my_long_long_max - 1; } + static constexpr long long (max)() throw() { return numeric_limits_details::my_long_long_max; } + static constexpr long long lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(long long); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(long long); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr long long epsilon() throw() { return 0; } + static constexpr long long round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr long long infinity() throw() { return static_cast(0); } + static constexpr long long quiet_NaN() throw() { return static_cast(0); } + static constexpr long long signaling_NaN() throw() { return static_cast(0); } + static constexpr long long denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for unsigned long long. @@ -623,44 +653,44 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static unsigned long long (min)() throw() { return 0; } - static unsigned long long (max)() throw() { return (numeric_limits_details::my_long_long_max * 2ULL) + 1; } - static unsigned long long lowest() throw() { return (min)(); } - - static const int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned long long); - static const int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned long long); - static const int max_digits10 = 0; - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_exact = true; - static const int radix = 2; - - static unsigned long long epsilon() throw() { return 0; } - static unsigned long long round_error() throw() { return 0; } - - static const int min_exponent = 0; - static const int min_exponent10 = 0; - static const int max_exponent = 0; - static const int max_exponent10 = 0; - static const bool has_infinity = false; - static const bool has_quiet_NaN = false; - static const bool has_signaling_NaN = false; - static const float_denorm_style has_denorm = denorm_absent; - static const bool has_denorm_loss = false; - - static unsigned long long infinity() throw() { return static_cast(0); } - static unsigned long long quiet_NaN() throw() { return static_cast(0); } - static unsigned long long signaling_NaN() throw() { return static_cast(0); } - static unsigned long long denorm_min() throw() { return static_cast(0); } - - static const bool is_iec559 = false; - static const bool is_bounded = true; - static const bool is_modulo = true; - static const bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; - static const bool tinyness_before = false; - static const float_round_style round_style = round_toward_zero; + static constexpr bool is_specialized = true; + + static constexpr unsigned long long (min)() throw() { return 0; } + static constexpr unsigned long long (max)() throw() { return (numeric_limits_details::my_long_long_max * 2ULL) + 1; } + static constexpr unsigned long long lowest() throw() { return (min)(); } + + static constexpr int digits = CONCEPT_FROM_GLIBCXX_DIGITS(unsigned long long); + static constexpr int digits10 = CONCEPT_FROM_GLIBCXX_DIGITS10(unsigned long long); + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int radix = 2; + + static constexpr unsigned long long epsilon() throw() { return 0; } + static constexpr unsigned long long round_error() throw() { return 0; } + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + + static constexpr unsigned long long infinity() throw() { return static_cast(0); } + static constexpr unsigned long long quiet_NaN() throw() { return static_cast(0); } + static constexpr unsigned long long signaling_NaN() throw() { return static_cast(0); } + static constexpr unsigned long long denorm_min() throw() { return static_cast(0); } + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = CONCEPT_FROM_GLIBCXX_INTEGRAL_TRAPS; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; }; // Specialization for float. @@ -668,46 +698,46 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static float (min)() throw() { return FLT_MIN; } - static float (max)() throw() { return FLT_MAX; } - static float lowest() throw() { return -FLT_MAX; } - - static const int digits = FLT_MANT_DIG; - static const int digits10 = FLT_DIG; - static const int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(FLT_MANT_DIG); - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = FLT_RADIX; - - static float epsilon() throw() { return FLT_EPSILON; } - static float round_error() throw() { return 0.5F; } - - static const int min_exponent = FLT_MIN_EXP; - static const int min_exponent10 = FLT_MIN_10_EXP; - static const int max_exponent = FLT_MAX_EXP; - static const int max_exponent10 = FLT_MAX_10_EXP; - - static const bool has_infinity = true; - static const bool has_quiet_NaN = true; - static const bool has_signaling_NaN = false; - static const bool has_denorm = true; - static const bool has_denorm_loss = false; - - static float infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_infinity(); } - static float quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_quiet_NaN(); } - static float signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_signaling_NaN(); } - static float denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_denorm_min(); } - - static const bool is_iec559 = true; - static const bool is_bounded = true; - static const bool is_modulo = false; - - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_to_nearest; + static constexpr bool is_specialized = true; + + static constexpr float (min)() throw() { return FLT_MIN; } + static constexpr float (max)() throw() { return FLT_MAX; } + static constexpr float lowest() throw() { return -FLT_MAX; } + + static constexpr int digits = FLT_MANT_DIG; + static constexpr int digits10 = FLT_DIG; + static constexpr int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(FLT_MANT_DIG); + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = FLT_RADIX; + + static constexpr float epsilon() throw() { return FLT_EPSILON; } + static constexpr float round_error() throw() { return 0.5F; } + + static constexpr int min_exponent = FLT_MIN_EXP; + static constexpr int min_exponent10 = FLT_MIN_10_EXP; + static constexpr int max_exponent = FLT_MAX_EXP; + static constexpr int max_exponent10 = FLT_MAX_10_EXP; + + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm = true; + static constexpr bool has_denorm_loss = false; + + static constexpr float infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_infinity(); } + static constexpr float quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_quiet_NaN(); } + static constexpr float signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_signaling_NaN(); } + static constexpr float denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_flt_denorm_min(); } + + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; }; // Specialization for double. @@ -715,46 +745,46 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static double (min)() throw() { return DBL_MIN; } - static double (max)() throw() { return DBL_MAX; } - static double lowest() throw() { return -DBL_MAX; } - - static const int digits = DBL_MANT_DIG; - static const int digits10 = DBL_DIG; - static const int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(DBL_MANT_DIG); - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = 2; // DBL_RADIX; - - static double epsilon() throw() { return DBL_EPSILON; } - static double round_error() throw() { return 0.5; } - - static const int min_exponent = DBL_MIN_EXP; - static const int min_exponent10 = DBL_MIN_10_EXP; - static const int max_exponent = DBL_MAX_EXP; - static const int max_exponent10 = DBL_MAX_10_EXP; - - static const bool has_infinity = true; - static const bool has_quiet_NaN = true; - static const bool has_signaling_NaN = false; - static const bool has_denorm = true; - static const bool has_denorm_loss = false; - - static double infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_infinity(); } - static double quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_quiet_NaN(); } - static double signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_signaling_NaN(); } - static double denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_denorm_min(); } - - static const bool is_iec559 = true; - static const bool is_bounded = true; - static const bool is_modulo = false; - - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_to_nearest; + static constexpr bool is_specialized = true; + + static constexpr double (min)() throw() { return DBL_MIN; } + static constexpr double (max)() throw() { return DBL_MAX; } + static constexpr double lowest() throw() { return -DBL_MAX; } + + static constexpr int digits = DBL_MANT_DIG; + static constexpr int digits10 = DBL_DIG; + static constexpr int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(DBL_MANT_DIG); + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; // DBL_RADIX; + + static constexpr double epsilon() throw() { return DBL_EPSILON; } + static constexpr double round_error() throw() { return 0.5; } + + static constexpr int min_exponent = DBL_MIN_EXP; + static constexpr int min_exponent10 = DBL_MIN_10_EXP; + static constexpr int max_exponent = DBL_MAX_EXP; + static constexpr int max_exponent10 = DBL_MAX_10_EXP; + + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm = true; + static constexpr bool has_denorm_loss = false; + + static constexpr double infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_infinity(); } + static constexpr double quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_quiet_NaN(); } + static constexpr double signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_signaling_NaN(); } + static constexpr double denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_dbl_denorm_min(); } + + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; }; // Specialization for long double. @@ -762,47 +792,50 @@ class numeric_limits { public: - static const bool is_specialized = true; - - static long double (min)() throw() { return LDBL_MIN; } - static long double (max)() throw() { return LDBL_MAX; } - static long double lowest() throw() { return -LDBL_MAX; } - - static const int digits = LDBL_MANT_DIG; - static const int digits10 = LDBL_DIG; - static const int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(LDBL_MANT_DIG); - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = 2; // DBL_RADIX; - - static long double epsilon() throw() { return LDBL_EPSILON; } - static long double round_error() throw() { return 0.5; } - - static const int min_exponent = LDBL_MIN_EXP; - static const int min_exponent10 = LDBL_MIN_10_EXP; - static const int max_exponent = LDBL_MAX_EXP; - static const int max_exponent10 = LDBL_MAX_10_EXP; - - static const bool has_infinity = true; - static const bool has_quiet_NaN = true; - static const bool has_signaling_NaN = false; - static const bool has_denorm = true; - static const bool has_denorm_loss = false; - - static long double infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_infinity(); } - static long double quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_quiet_NaN(); } - static long double signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_signaling_NaN(); } - static long double denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_denorm_min(); } - - static const bool is_iec559 = true; - static const bool is_bounded = true; - static const bool is_modulo = false; - - static const bool traps = false; - static const bool tinyness_before = false; - static const float_round_style round_style = round_to_nearest; + static constexpr bool is_specialized = true; + + static constexpr long double (min)() throw() { return LDBL_MIN; } + static constexpr long double (max)() throw() { return LDBL_MAX; } + static constexpr long double lowest() throw() { return -LDBL_MAX; } + + static constexpr int digits = LDBL_MANT_DIG; + static constexpr int digits10 = LDBL_DIG; + static constexpr int max_digits10 = CONCEPT_FROM_GLIBCXX_MAX_DIGITS10(LDBL_MANT_DIG); + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; // DBL_RADIX; + + static constexpr long double epsilon() throw() { return LDBL_EPSILON; } + static constexpr long double round_error() throw() { return 0.5; } + + static constexpr int min_exponent = LDBL_MIN_EXP; + static constexpr int min_exponent10 = LDBL_MIN_10_EXP; + static constexpr int max_exponent = LDBL_MAX_EXP; + static constexpr int max_exponent10 = LDBL_MAX_10_EXP; + + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm = true; + static constexpr bool has_denorm_loss = false; + + static constexpr long double infinity() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_infinity(); } + static constexpr long double quiet_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_quiet_NaN(); } + static constexpr long double signaling_NaN() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_signaling_NaN(); } + static constexpr long double denorm_min() throw() { return numeric_limits_details::my_value_that_needs_to_be_provided_ldbl_denorm_min(); } + + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; }; } + #if defined(__GNUC__) && defined(__XTENSA__) + } + #endif #endif // LIMITS_2010_02_23_ diff --git a/examples/chapter11_07/src/util/STL/memory b/examples/chapter11_07/src/util/STL/memory index 9167b70b9..92bf3cb6f 100644 --- a/examples/chapter11_07/src/util/STL/memory +++ b/examples/chapter11_07/src/util/STL/memory @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) @@ -8,21 +8,12 @@ #ifndef MEMORY_2010_02_23_ #define MEMORY_2010_02_23_ - #include - #include - #include #include - #if defined(_MSC_VER) - #define STL_LOCAL_ALIGNAS(n) - #else - #define STL_LOCAL_ALIGNAS(n) alignas(n) - #endif - // Provide the default placement versions of operator new. - inline void* operator new (size_t, void* my_p) STL_LOCAL_NOEXCEPT { return my_p; } - inline void* operator new[](size_t, void* my_p) STL_LOCAL_NOEXCEPT { return my_p; } + inline void* operator new (size_t, void* my_p) noexcept { return my_p; } + inline void* operator new[](size_t, void* my_p) noexcept { return my_p; } // Implement the standard allocator (std::allocator). namespace std @@ -41,7 +32,7 @@ allocator_base(const allocator_base&) throw() { } // The allocator's default buffer size. - static STL_LOCAL_CONSTEXPR size_type buffer_size = 64U; + static constexpr size_type buffer_size = 64U; // The allocator's buffer type. struct buffer_type @@ -50,10 +41,9 @@ }; // The allocator's memory allocation. - template static void* do_allocate(const size_type size) { - STL_LOCAL_ALIGNAS(8) static buffer_type buffer; + alignas(8) static buffer_type buffer; static std::uint8_t* get_ptr = buffer.data; @@ -62,8 +52,7 @@ // Increment the get-pointer for the next allocation. // Be sure to handle the inner-buffer alignment. - const std::uint_fast8_t align_increment = inner_buffer_alignment - std::uint_fast8_t(size % inner_buffer_alignment); - const size_type buffer_increment = size + align_increment; + const size_type buffer_increment = size; get_ptr += buffer_increment; @@ -118,12 +107,11 @@ return false; } - template + template class allocator; - template - class allocator : public allocator_base + template<> + class allocator : public allocator_base { public: typedef void value_type; @@ -131,20 +119,16 @@ typedef const value_type* const_pointer; template - struct rebind { typedef allocator other; }; + struct rebind { typedef allocator other; }; }; - template + template class allocator : public allocator_base { public: static_assert(sizeof(T) <= buffer_size, "The size of the allocation object can not exceed the buffer size."); - static_assert(inner_buffer_alignment <= buffer_size, - "The granularity of the inner-buffer alignment can not exceed the buffer size."); - typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; @@ -156,10 +140,10 @@ allocator(const allocator&) throw() : allocator_base(allocator()) { } template - allocator(const allocator&) throw() { } + allocator(const allocator&) throw() { } template - struct rebind { typedef allocator other; }; + struct rebind { typedef allocator other; }; size_type max_size() const throw() { @@ -170,11 +154,11 @@ const_pointer address(const_reference x) const { return &x; } pointer allocate(size_type count, - typename allocator::const_pointer = nullptr) + typename allocator::const_pointer = nullptr) { const size_type chunk_size = count * sizeof(value_type); - void* p = do_allocate(chunk_size); + void* p = do_allocate(chunk_size); return static_cast(p); } @@ -227,6 +211,69 @@ { return detail::addressof_impl::f(detail::addr_impl_ref(v), 0); } + + #if 0 + template + struct allocator_traits + { + public: + using allocator_type = AllocatorType; + using value_type = typename AllocatorType::value_type; + using pointer = value_type*; + using const_pointer = const value_type*; + using void_pointer = void*; + using const_void_pointer = const void*; + using difference_type = std::ptrdiff_t; + using size_type = std::size_t; + + template + struct rebind_alloc + { + using type = typename allocator_type::template rebind::other; + }; + + //struct rebind_alloc + //{ + // using type = value_type; + //}; + + static pointer allocate(allocator_type& a, size_type n) + { + return a.allocate(n); + } + + static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint) + { + return my_allocate(a, n, hint, 0); + } + + template + static void construct(allocator_type& a, OtherValueType* p, const OtherValueType& x) + { + a.construct(p, x); + } + + template + static void destroy(allocator_type& a, OtherValueType* p) + { + a.destroy(p); + } + + static void deallocate(allocator_type& a, pointer p, size_type n) + { + a.deallocate(p, n); + } + + private: + template + static typename OtherAllocatorType::pointer my_allocate(OtherAllocatorType& a, size_type n, const_void_pointer hint, int) + { + return a.allocate(n, hint); + } + }; + #endif } + #include + #endif // MEMORY_2010_02_23_ diff --git a/examples/chapter11_07/src/util/STL/random b/examples/chapter11_07/src/util/STL/random index a47cfc6b6..2c370b07e 100644 --- a/examples/chapter11_07/src/util/STL/random +++ b/examples/chapter11_07/src/util/STL/random @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2018. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2018 - 2022. // 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) @@ -11,162 +11,1709 @@ #include #include #include - #include - #include + #include + #include + #include - /* - Portions of . The following portions will be included: + // Implement some of for compilers that do not yet support it. - linear_congruential_engine - mersenne_twister_engine - subtract_with_carry_engine - discard_block_engine - independent_bits_engine - shuffle_order_engine - [rand.predef] - uniform_int_distribution - */ + extern "C" unsigned int my_hardware_random_device_generator(void); + extern "C" unsigned char my_hardware_random_device_entropy (void); - namespace std + namespace std { + + namespace rnd__detail { + + template(std::numeric_limits::digits)> + struct rnd__shift + { + static const UnsignedIntegralType rnd__value = 0U; + }; + + template + struct rnd__shift + { + static const UnsignedIntegralType rnd__value = UnsignedIntegralType(1ULL << rnd__word_size); + }; + + template + struct rnd__select_uint_least_t + { + static_assert(rnd__which < 0, "Error: would be too much trouble for a slow result"); + }; + + template + struct rnd__select_uint_least_t + { + typedef unsigned int type; + }; + + template + struct rnd__select_uint_least_t { - class seed_seq + typedef unsigned long type; + }; + + template + struct rnd__select_uint_least_t + { + typedef unsigned long long type; + }; + + // Assume a != 0, a < m, c < m, x < m. + template= ParamM - 1), + bool rnd__schrage_ok = ParamM % ParamA < ParamM / ParamA> + struct rnd__inner_mod + { + typedef T _Tp2; + static T + + rnd__calc(T rnd__x) { - public: - using result_type = uint_least32_t; + return static_cast((_Tp2(ParamA) * rnd__x + ParamC) % ParamM); + } + }; - seed_seq() : internal_sequence() { } + // Schrage. + template + struct rnd__inner_mod + { + // General case for x = (ax + c) mod m -- use Schrage's algorithm + // to avoid integer overflow. + // + // Preconditions: a > 0, m > 0. + // + // Note: only works correctly for ParamM % ParamA < ParamM / ParamA. + static T rnd__calc(T rnd__x) + { + if (ParamA == 1) + { + rnd__x %= ParamM; + } + else + { + constexpr T rnd__seed_sequence = ParamM / ParamA; + constexpr T rnd__long_lag_r = ParamM % ParamA; - template - seed_seq(const std::initializer_list& init_list) - : internal_sequence(init_list.begin(), init_list.end()) { } + T rnd__t1 = ParamA * (rnd__x % rnd__seed_sequence); + T rnd__t2 = rnd__long_lag_r * (rnd__x / rnd__seed_sequence); - template - seed_seq(input_iterator_type first, input_iterator_type last) - : internal_sequence(first, last) { } + if (rnd__t1 >= rnd__t2) + { + rnd__x = rnd__t1 - rnd__t2; + } + else + { + rnd__x = ParamM - rnd__t2 + rnd__t1; + } + } - template - void generate(random_iterator_type first, random_iterator_type last) const + if(ParamC != 0) { - typedef typename std::iterator_traits::value_type value_type; + const T rnd__value_d = ParamM - rnd__x; - std::fill(first, last, static_cast(0x8B8B8B8BU)); + if (rnd__value_d > ParamC) + { + rnd__x += ParamC; + } + else + { + rnd__x = ParamC - rnd__value_d; + } + } - std::size_t s = internal_sequence.size(); + return rnd__x; + } + }; - std::size_t n = last - first; + // Special cases: + // - for m == 2^n or m == 0, unsigned integer overflow is safe. + // - a * (m - 1) + c fits in T, there is no overflow. + template + struct rnd__inner_mod + { + static T rnd__calc(T rnd__x) + { + T rnd__res = ParamA * rnd__x + ParamC; - std::size_t t = (n >= 623) ? 11 : - (n >= 68) ? 7 : - (n >= 39) ? 5 : - (n >= 7) ? 3 : - (n - 1)/2; + if (ParamM) + { + rnd__res %= ParamM; + } - std::size_t p = (n - t) / 2; - std::size_t q = p + t; - std::size_t m = (std::max)(s + 1, n); + return rnd__res; + } + }; - value_type mask = 0xFFFFFFFFU; - for(std::size_t k = 0; k < m; ++k) - { - value_type r1(*(first + (k % n)) ^ *(first + ((k + p) % n)) ^ *(first + (((k + n) - 1) % n))); + template + inline T rnd__mod(T rnd__x) + { + return rnd__inner_mod::rnd__calc(rnd__x); + } + + template + OutputIterator rnd__normalize(InputIterator rnd__first, + InputIterator rnd__last, + OutputIterator rnd__result, + const T& rnd__factor) + { + for( ; rnd__first != rnd__last; ++rnd__first, ++rnd__result) + { + *rnd__result = *rnd__first / rnd__factor; + } - r1 = r1 ^ (r1 >> 27); - r1 = (r1 * 1664525U) & mask; + return rnd__result; + } - value_type r2(r1 + ((k == 0) ? s : - (k <= s) ? k % n + internal_sequence[k - 1] : - (k % n))); + } } // namespace std::rnd__detail - *(first + ((k + p) % n)) = (*(first + ((k + p) % n)) + r1) & mask; - *(first + ((k + q) % n)) = (*(first + ((k + q) % n)) + r2) & mask; - *(first + (k % n)) = r2; - } + namespace std { - for(std::size_t k = m; k < m + n; ++k) - { - value_type r3((*(first + (k % n)) + *(first + ((k + p) % n)) + *(first + (k+n-1)%n)) & mask); + // These classes define objects which provide random + // or pseudorandom numbers, either from a discrete or + // a continuous interval. + + // Generate pseudorandom numbers via linear function + // x_{i+1} -> (ax_{i} + c) % m + // + // The template parameter UnsignedIntegralType must be an unsigned + // integral type large enough to store values up to (ParamM-1). + // If the template parameter ParamM is 0, the modulus ParamM used is + // std::numeric_limits::max() + 1. Otherwise, + // the template parameters ParamA and ParamC must be less than ParamM. - r3 = r3 ^ (r3 >> 27); - r3 = (r3 * 1566083941U) & mask; + template + class linear_congruential_engine + { + private: + static_assert(std::is_unsigned::value, + "Error: result_type must be an unsigned integral type"); - value_type r4 = static_cast(r3 - (k % n)); + static_assert(ParamM == 0u || (ParamA < ParamM && ParamC < ParamM), + "Error: template argument substituting ParamM out of bounds"); - *(first + ((k + p) % n)) ^= r3; - *(first + ((k + q) % n)) ^= r4; - *(first + (k % n)) = r4; - } + public: + typedef UnsignedIntegralType result_type; + + static const result_type multiplier = ParamA; + static const result_type increment = ParamC; + static const result_type modulus = ParamM; + static const result_type default_seed = 1U; + + explicit linear_congruential_engine(result_type rnd__seed = default_seed) + { + seed(rnd__seed); + } + + template::value>::type> + explicit linear_congruential_engine(_Sseq& rnd__seed_sequence) + { + seed(rnd__seed_sequence); + } + + void seed(result_type rnd__seed = default_seed); + + static constexpr result_type min() + { + return ParamC == 0u ? 1u : 0u; + } + + static constexpr result_type max() + { + return ParamM - 1u; + } + + void discard(unsigned long long rnd__z) + { + for( ; rnd__z != 0ULL; --rnd__z) + { + (*this)(); + } + } + + result_type operator()() + { + my_elems = rnd__detail::rnd__mod(my_elems); + + return my_elems; + } + + friend bool operator==(const linear_congruential_engine& left, + const linear_congruential_engine& right) + { + return (left.my_elems == right.my_elems); + } + + private: + UnsignedIntegralType my_elems; + }; + + template + inline bool operator!=(const std::linear_congruential_engine& left, + const std::linear_congruential_engine& right) + { + return !(left == right); + } + + // A generalized feedback shift register discrete random number generator. + // + // This algorithm avoids multiplication and division and is designed to be + // friendly to a pipelined architecture. If the parameters are chosen + // correctly, this generator will produce numbers with a very long period and + // fairly good apparent entropy, although still not cryptographically strong. + // + // The best way to use this generator is with the predefined mt19937 class. + // + // This algorithm was originally invented by Makoto Matsumoto and + // Takuji Nishimura. + // + // rnd__word_size Word size, the number of bits in each element of + // the state vector. + // ParamN The degree of recursion. + // ParamM The period parameter. + // rnd__long_lag_r The separation point bit index. + // ParamA The last row of the twist matrix. + // ParamU The first right-shift tempering matrix parameter. + // rnd__value_d The first right-shift tempering matrix mask. + // rnd__seed The first left-shift tempering matrix parameter. + // rnd__value_b The first left-shift tempering matrix mask. + // ParamT The second left-shift tempering matrix parameter. + // ParamC The second left-shift tempering matrix mask. + // ParamL The second right-shift tempering matrix parameter. + // rnd__value_f Initialization multiplier. + + template + class mersenne_twister_engine + { + private: + static_assert(std::is_unsigned::value, + "result_type must be an unsigned integral type"); + + static_assert(1u <= ParamM && ParamM <= ParamN, + "template argument substituting ParamM out of bounds"); + + static_assert(rnd__long_lag_r <= rnd__word_size, "template argument substituting rnd__long_lag_r out of bound"); + static_assert(ParamU <= rnd__word_size, "template argument substituting ParamU out of bound"); + static_assert(rnd__seed <= rnd__word_size, "template argument substituting rnd__seed out of bound"); + static_assert(ParamT <= rnd__word_size, "template argument substituting ParamT out of bound"); + static_assert(ParamL <= rnd__word_size, "template argument substituting ParamL out of bound"); + static_assert(rnd__word_size <= std::numeric_limits::digits, + "template argument substituting rnd__word_size out of bound"); + static_assert(ParamA <= (rnd__detail::rnd__shift::rnd__value - 1), + "template argument substituting ParamA out of bound"); + static_assert(rnd__value_b <= (rnd__detail::rnd__shift::rnd__value - 1), + "template argument substituting rnd__value_b out of bound"); + static_assert(ParamC <= (rnd__detail::rnd__shift::rnd__value - 1), + "template argument substituting ParamC out of bound"); + static_assert(rnd__value_d <= (rnd__detail::rnd__shift::rnd__value - 1), + "template argument substituting rnd__value_d out of bound"); + static_assert(rnd__value_f <= (rnd__detail::rnd__shift::rnd__value - 1), + "template argument substituting rnd__value_f out of bound"); + + public: + typedef UnsignedIntegralType result_type; + + static const size_t word_size = rnd__word_size; + static const size_t state_size = ParamN; + static const size_t shift_size = ParamM; + static const size_t mask_bits = rnd__long_lag_r; + static const result_type xor_mask = ParamA; + static const size_t tempering_u = ParamU; + static const result_type tempering_d = rnd__value_d; + static const size_t tempering_s = rnd__seed; + static const result_type tempering_b = rnd__value_b; + static const size_t tempering_t = ParamT; + static const result_type tempering_c = ParamC; + static const size_t tempering_l = ParamL; + static const result_type initialization_multiplier = rnd__value_f; + static const result_type default_seed = 5489u; + + // constructors and member function + explicit mersenne_twister_engine(result_type rnd__s = default_seed) + { + seed(rnd__s); + } + + template::value>::type> + explicit mersenne_twister_engine(_Sseq& rnd__seed_sequence) + { + seed(rnd__seed_sequence); + } + + void seed(result_type __sd = default_seed); + + static constexpr result_type min() + { + return 0; + } + + static constexpr result_type max() + { + return rnd__detail::rnd__shift::rnd__value - 1; + } + + void discard(unsigned long long rnd__z); + + result_type operator()(); + + friend bool operator==(const mersenne_twister_engine& left, + const mersenne_twister_engine& right) + { + return ( std::equal(left.my_elems, left.my_elems + state_size, right.my_elems) + && left.my_p == right.my_p); + } + + private: + UnsignedIntegralType my_elems[state_size]; + size_t my_p; + + void rnd__m_gen_rand(); + }; + + template + inline bool operator!=(const std::mersenne_twister_engine& left, + const std::mersenne_twister_engine& right) + { + return !(left == right); + } + + // Marsaglia-Zaman generator. + // + // This is a model of a Generalized Fibonacci discrete random number + // generator, sometimes referred to as the SWC generator. + // + // A discrete random number generator that produces pseudorandom + // numbers using: + // x_{i} -> (x_{i - s} - x_{i - r} - carry_{i-1}) % m + // + + template + class subtract_with_carry_engine + { + private: + static_assert(std::is_unsigned::value, + "result_type must be an unsigned integral type"); + + static_assert(0u < rnd__seed && rnd__seed < rnd__long_lag_r, "0 < s < r"); + + static_assert(0u < rnd__word_size && rnd__word_size <= std::numeric_limits::digits, + "template argument substituting rnd__word_size out of bounds"); + + public: + typedef UnsignedIntegralType result_type; + + // parameter values + static const size_t word_size = rnd__word_size; + static const size_t short_lag = rnd__seed; + static const size_t long_lag = rnd__long_lag_r; + static const result_type default_seed = (result_type) 19780503ULL; + + explicit subtract_with_carry_engine(result_type __sd = default_seed) + { + seed(__sd); + } + + template::value>::type> + explicit subtract_with_carry_engine(_Sseq& rnd__seed_sequence) + { + seed(rnd__seed_sequence); + } + + void seed(result_type rnd__s = default_seed); + + static constexpr result_type min() { return 0; } + + static constexpr result_type max() + { + return rnd__detail::rnd__shift::rnd__value - 1; + } + + result_type operator()() + { + // Derive short lag index from current index. + std::int32_t rnd__ps = (std::int32_t) my_p - (std::int32_t) short_lag; + + if(rnd__ps < 0) + { + rnd__ps += (std::int32_t) long_lag; + } + + // Calculate new x(i) without overflow or division. + // NB: Thanks to the requirements for UnsignedIntegralType, rnd__elems[rnd__m_p] + rnd__m_carry + // cannot overflow. + UnsignedIntegralType rnd__xi; + + if(my_elems[rnd__ps] >= my_elems[my_p] + my_carry) + { + rnd__xi = my_elems[rnd__ps] - my_elems[my_p] - my_carry; + + my_carry = 0; + } + else + { + rnd__xi = (rnd__detail::rnd__shift::rnd__value - my_elems[my_p] - my_carry + my_elems[rnd__ps]); + + my_carry = 1; + } + + my_elems[my_p] = rnd__xi; + + // Adjust current index to loop around in ring buffer. + if (++my_p >= long_lag) + { + my_p = 0; } - template - void param(output_iterator_type destination) const + return rnd__xi; + } + + void discard(unsigned long long rnd__z) + { + for (; rnd__z != 0ULL; --rnd__z) { - static_cast(destination); + (*this)(); } + } + + friend inline bool operator==(const subtract_with_carry_engine& left, + const subtract_with_carry_engine& right) + { + return ( std::equal(left.my_elems, left.my_elems + long_lag, right.my_elems) + && left.my_carry == right.my_carry + && left.my_p == right.my_p); + } + + private: + UnsignedIntegralType my_elems[long_lag]; + UnsignedIntegralType my_carry; + size_t my_p; + }; + + template + inline bool operator!=(const std::subtract_with_carry_engine& left, + const std::subtract_with_carry_engine& right) + { + return !(left == right); + } + + + // Produces random numbers from some base engine + // by discarding blocks of data. + + template + class discard_block_engine + { + private: + static_assert(1 <= rnd__long_lag_r && rnd__long_lag_r <= rnd__p, + "template argument substituting rnd__long_lag_r out of bounds"); + + public: + typedef typename _RandomNumberEngine::result_type result_type; + + static const size_t block_size = rnd__p; + static const size_t used_block = rnd__long_lag_r; + + discard_block_engine() : my_b(), my_n(0) { } + + explicit discard_block_engine(const _RandomNumberEngine& rnd__eng) + : my_b(rnd__eng), + my_n(0) { } + + explicit discard_block_engine(_RandomNumberEngine&& rnd__eng) + : my_b(std::move(rnd__eng)), + my_n(0) { } + + explicit discard_block_engine(result_type rnd__seed) + : my_b(rnd__seed), + my_n(0) { } + + template::value + && !std::is_same<_Sseq, _RandomNumberEngine >::value)>::type> + explicit discard_block_engine(_Sseq& rnd__seed_sequence) + : my_b(rnd__seed_sequence), + my_n(0) { } + + void seed() + { + my_b.seed(); + my_n = 0; + } + + void seed(result_type rnd__seed) + { + my_b.seed(rnd__seed); + my_n = 0; + } + + template + void seed(_Sseq& rnd__seed_sequence) + { + my_b.seed(rnd__seed_sequence); + my_n = 0; + } + + const _RandomNumberEngine& base() const noexcept + { + return my_b; + } + + static constexpr result_type min() + { + return _RandomNumberEngine::min(); + } + + static constexpr result_type max() + { + return _RandomNumberEngine::max(); + } - size_t size() const { return internal_sequence.size(); } - - seed_seq(const seed_seq&) = delete; - void operator=(const seed_seq&) = delete; - - private: - std::vector internal_sequence; - }; - - template - class mersenne_twister_engine - { - public: - using result_type = unsigned_integral_type; - - static const result_type default_seed = 0U; - - explicit mersenne_twister_engine(result_type val = default_seed) + void discard(unsigned long long rnd__z) + { + for( ; rnd__z != 0ULL; --rnd__z) { + (*this)(); } + } + + result_type operator()(); + + friend bool operator==(const discard_block_engine& left, + const discard_block_engine& right) + { + return left.my_b == right.my_b + && left.my_n == right.my_n; + } + + private: + _RandomNumberEngine my_b; + size_t my_n; + }; + + template + inline bool operator!=(const std::discard_block_engine<_RandomNumberEngine, + rnd__p, + rnd__long_lag_r>& left, + const std::discard_block_engine<_RandomNumberEngine, + rnd__p, + rnd__long_lag_r>& right) + { + return !(left == right); + } + + + // Produces random numbers by combining random numbers + // from some base engine to produce random numbers + // with a specifies number of bits rnd__k. + + template + class shuffle_order_engine + { + private: + static_assert(1u <= rnd__k, "template argument substituting " + "rnd__k out of bound"); + + public: + typedef typename _RandomNumberEngine::result_type result_type; + + static const size_t table_size = rnd__k; + + shuffle_order_engine() : rnd__m_b() + { + rnd__m_initialize(); + } + + explicit shuffle_order_engine(const _RandomNumberEngine& rnd__eng) + : rnd__m_b(rnd__eng) + { + rnd__m_initialize(); + } + + explicit shuffle_order_engine(_RandomNumberEngine&& rnd__eng) + : rnd__m_b(std::move(rnd__eng)) + { + rnd__m_initialize(); + } + + explicit shuffle_order_engine(result_type rnd__seed) + : rnd__m_b(rnd__seed) + { + rnd__m_initialize(); + } + + template::value + && !std::is_same<_Sseq, _RandomNumberEngine >::value)>::type> + explicit shuffle_order_engine(_Sseq& rnd__seed_sequence) + : rnd__m_b(rnd__seed_sequence) + { + rnd__m_initialize(); + } + + void seed() + { + rnd__m_b.seed(); + + rnd__m_initialize(); + } + + void seed(result_type rnd__seed) + { + rnd__m_b.seed(rnd__seed); + + rnd__m_initialize(); + } + + template + void seed(_Sseq& rnd__seed_sequence) + { + rnd__m_b.seed(rnd__seed_sequence); + + rnd__m_initialize(); + } + + const _RandomNumberEngine& base() const noexcept + { + return rnd__m_b; + } + + static constexpr result_type min() + { + return _RandomNumberEngine::min(); + } + + static constexpr result_type max() + { + return _RandomNumberEngine::max(); + } - template - explicit mersenne_twister_engine(seed_sequence_type& q) + void discard(unsigned long long rnd__z) + { + for(; rnd__z != 0ULL; --rnd__z) { + (*this)(); } + } + + result_type operator()(); - void seed(result_type val = default_seed) + friend bool operator==(const shuffle_order_engine& left, + const shuffle_order_engine& right) + { + return ( left.rnd__m_b == right.rnd__m_b + && std::equal(left.rnd__m_v, left.rnd__m_v + rnd__k, right.rnd__m_v) + && left.rnd__m_y == right.rnd__m_y); + } + + private: + void rnd__m_initialize() + { + for(size_t rnd__i = 0; rnd__i < rnd__k; ++rnd__i) { + rnd__m_v[rnd__i] = rnd__m_b(); } - template - void seed(seed_sequence_type& q) + rnd__m_y = rnd__m_b(); + } + + _RandomNumberEngine rnd__m_b; + result_type rnd__m_v[rnd__k]; + result_type rnd__m_y; + }; + + template + inline bool operator!=(const std::shuffle_order_engine<_RandomNumberEngine, rnd__k>& left, + const std::shuffle_order_engine<_RandomNumberEngine, rnd__k>& right) + { + return !(left == right); + } + + template + const UnsignedIntegralType linear_congruential_engine::multiplier; + + template + const UnsignedIntegralType linear_congruential_engine::increment; + + template + const UnsignedIntegralType linear_congruential_engine::modulus; + + template + const UnsignedIntegralType linear_congruential_engine::default_seed; + + template + void linear_congruential_engine::seed(result_type rnd__seed) + { + if(( (rnd__detail::rnd__mod(ParamC) == 0) + && (rnd__detail::rnd__mod(rnd__seed) == 0))) + { + my_elems = 1; + } + else + { + my_elems = rnd__detail::rnd__mod(rnd__seed); + } + } + + template + const size_t mersenne_twister_engine::word_size; + + template + const size_t mersenne_twister_engine::state_size; + + template + const size_t mersenne_twister_engine::shift_size; + + template + const size_t mersenne_twister_engine::mask_bits; + + template + const UnsignedIntegralType mersenne_twister_engine::xor_mask; + + template + const size_t mersenne_twister_engine::tempering_u; + +template + const UnsignedIntegralType mersenne_twister_engine::tempering_d; + + template + const size_t mersenne_twister_engine::tempering_s; + +template + const UnsignedIntegralType mersenne_twister_engine::tempering_b; + + template + const size_t mersenne_twister_engine::tempering_t; + +template + const UnsignedIntegralType mersenne_twister_engine::tempering_c; + + template + const size_t mersenne_twister_engine::tempering_l; + +template + const UnsignedIntegralType mersenne_twister_engine::initialization_multiplier; + + template + const UnsignedIntegralType mersenne_twister_engine::default_seed; + + template + void mersenne_twister_engine::seed(result_type __sd) + { + my_elems[0] = rnd__detail::rnd__mod::rnd__value>(__sd); + + for (size_t rnd__i = 1; rnd__i < state_size; ++rnd__i) + { + UnsignedIntegralType rnd__x = my_elems[rnd__i - 1]; + + rnd__x ^= rnd__x >> (rnd__word_size - 2); + rnd__x *= rnd__value_f; + rnd__x += rnd__detail::rnd__mod(rnd__i); + + my_elems[rnd__i] = rnd__detail::rnd__mod::rnd__value>(rnd__x); + } + + my_p = state_size; + } + + template + void mersenne_twister_engine::rnd__m_gen_rand(void) + { + const UnsignedIntegralType __upper_mask = (~UnsignedIntegralType()) << rnd__long_lag_r; + const UnsignedIntegralType __lower_mask = ~__upper_mask; + + for(size_t rnd__k = 0; rnd__k < (ParamN - ParamM); ++rnd__k) + { + UnsignedIntegralType rnd__y = ((my_elems[rnd__k] & __upper_mask) | (my_elems[rnd__k + 1] & __lower_mask)); + + my_elems[rnd__k] = (my_elems[rnd__k + ParamM] ^ (rnd__y >> 1) ^ ((rnd__y & 0x01) ? ParamA : 0)); + } + + for (size_t rnd__k = (ParamN - ParamM); rnd__k < (ParamN - 1); ++rnd__k) + { + UnsignedIntegralType rnd__y = ((my_elems[rnd__k] & __upper_mask) | (my_elems[rnd__k + 1] & __lower_mask)); + + my_elems[rnd__k] = (my_elems[rnd__k + (ParamM - ParamN)] ^ (rnd__y >> 1) ^ ((rnd__y & 0x01) ? ParamA : 0)); + } + + UnsignedIntegralType rnd__y = ((my_elems[ParamN - 1] & __upper_mask) | (my_elems[0] & __lower_mask)); + + my_elems[ParamN - 1] = (my_elems[ParamM - 1] ^ (rnd__y >> 1) ^ ((rnd__y & 0x01) ? ParamA : 0)); + + my_p = 0; + } + + template + void mersenne_twister_engine::discard(unsigned long long rnd__z) + { + while(rnd__z > state_size - my_p) + { + rnd__z -= state_size - my_p; + rnd__m_gen_rand(); + } + + my_p += rnd__z; + } + + template + typename mersenne_twister_engine::result_type + mersenne_twister_engine::operator()() + { + if (my_p >= state_size) + { + rnd__m_gen_rand(); + } + + result_type rnd__z = my_elems[my_p++]; + + rnd__z ^= (rnd__z >> ParamU) & rnd__value_d; + rnd__z ^= (rnd__z << rnd__seed) & rnd__value_b; + rnd__z ^= (rnd__z << ParamT) & ParamC; + rnd__z ^= (rnd__z >> ParamL); + + return rnd__z; + } + + template + const size_t subtract_with_carry_engine::word_size; + + template + const size_t subtract_with_carry_engine::short_lag; + + template + const size_t subtract_with_carry_engine::long_lag; + + template + const UnsignedIntegralType subtract_with_carry_engine::default_seed; + + template + void subtract_with_carry_engine::seed(result_type rnd__value) + { + std::linear_congruential_engine + + __lcg(rnd__value == 0u ? default_seed : rnd__value); + + const size_t ParamN = (rnd__word_size + 31) / 32; + + for (size_t rnd__i = 0; rnd__i < long_lag; ++rnd__i) + { + UnsignedIntegralType rnd__sum = 0u; + UnsignedIntegralType rnd__factor = 1u; + + for(size_t rnd__j = 0; rnd__j < ParamN; ++rnd__j) { + rnd__sum += rnd__detail::rnd__mod::rnd__value>(__lcg()) * rnd__factor; + + rnd__factor *= rnd__detail::rnd__shift::rnd__value; } - }; - - typedef mersenne_twister_engine - mt19937; + + my_elems[rnd__i] = + rnd__detail::rnd__mod::rnd__value>(rnd__sum); + } + + my_carry = (my_elems[long_lag - 1] == 0) ? 1 : 0; + my_p = 0; + } + + template + const size_t discard_block_engine<_RandomNumberEngine, + rnd__p, + rnd__long_lag_r>::block_size; + + template + const size_t discard_block_engine<_RandomNumberEngine, + rnd__p, + rnd__long_lag_r>::used_block; + + template + typename discard_block_engine<_RandomNumberEngine, + rnd__p, + rnd__long_lag_r>::result_type + discard_block_engine<_RandomNumberEngine, rnd__p, rnd__long_lag_r>::operator()() + { + if (my_n >= used_block) + { + my_b.discard(block_size - my_n); + my_n = 0; + } + + ++my_n; + + return my_b(); + } + + template + const size_t shuffle_order_engine<_RandomNumberEngine, rnd__k>::table_size; + + template + typename shuffle_order_engine<_RandomNumberEngine, rnd__k>::result_type + shuffle_order_engine<_RandomNumberEngine, rnd__k>::operator()() + { + size_t rnd__j = rnd__k * ((rnd__m_y - rnd__m_b.min()) / (rnd__m_b.max() - rnd__m_b.min() + 1.0L)); + + rnd__m_y = rnd__m_v[rnd__j]; + rnd__m_v[rnd__j] = rnd__m_b(); + + return rnd__m_y; } + // The classic Minimum Standard rand0 of Lewis, Goodman, and Miller. + typedef linear_congruential_engine minstd_rand0; + + // An alternative LCR (Lehmer Generator function). + typedef linear_congruential_engine minstd_rand; + + // The classic Mersenne Twister. + // M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally + // Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions + // on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + + typedef mersenne_twister_engine + mt19937; + + // An alternative Mersenne Twister (64-bit). + typedef mersenne_twister_engine + mt19937_64; + + typedef subtract_with_carry_engine ranlux24_base; + typedef subtract_with_carry_engine ranlux48_base; + + typedef discard_block_engine ranlux24; + typedef discard_block_engine ranlux48; + + typedef shuffle_order_engine knuth_b; + + typedef minstd_rand0 default_random_engine; + + class random_device + { + public: + using result_type = unsigned int; + + random_device() { } + + explicit random_device(const char*) { } + + static constexpr result_type(min)() noexcept + { + return static_cast(UINT8_C(0)); + } + + static constexpr result_type(max)() noexcept + { + return static_cast(static_cast(INTMAX_C(-1))); + } + + // Not conformant with the standard return type of double. + float entropy() const noexcept + { + const unsigned char e = my_hardware_random_device_entropy(); + + return ((e > static_cast(UINT8_C(32))) ? 32.0F : float(e)); + } + + result_type operator()() + { + return static_cast(my_hardware_random_device_generator()); + } + + random_device(const random_device&) = delete; + random_device& operator=(const random_device&) = delete; + }; + + } // namespace std + #endif // RANDOM_2018_06_10_ diff --git a/examples/chapter11_07/src/util/STL/ratio b/examples/chapter11_07/src/util/STL/ratio index 9ab68582e..bcfe973a9 100644 --- a/examples/chapter11_07/src/util/STL/ratio +++ b/examples/chapter11_07/src/util/STL/ratio @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -/// \author (c) Marco Paland (info@paland.com) +/// \author (c) Marco Paland (info (AT) paland.com) /// 2011-2012, PALANDesign Hannover, Germany /// /// \license LGPLv3 diff --git a/examples/chapter11_07/src/util/STL/span b/examples/chapter11_07/src/util/STL/span index ae2213c0e..1c5d121e3 100644 --- a/examples/chapter11_07/src/util/STL/span +++ b/examples/chapter11_07/src/util/STL/span @@ -1,11 +1,12 @@ -// This is significant simplification of an existing work: +// This is a significant simplification of an existing work: +// Comments from the original work follow. // This is an implementation of std::span from P0122R7 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r7.pdf /////////////////////////////////////////////////////////////////////////////// // Copyright Tristan Brindle 2018. -// Copyright Christopher Kormanyos 2019. +// Copyright Christopher Kormanyos 2019 - 2024. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file ../../LICENSE_1_0.txt or copy at // https://www.boost.org/LICENSE_1_0.txt) @@ -26,7 +27,7 @@ using byte = unsigned char; STL_LOCAL_CONSTEXPR std::size_t dynamic_extent = - (std::numeric_limits::max)(); + static_cast((std::numeric_limits::max)()); template diff --git a/examples/chapter11_07/src/util/STL/stdexcept b/examples/chapter11_07/src/util/STL/stdexcept new file mode 100644 index 000000000..5e7a8c527 --- /dev/null +++ b/examples/chapter11_07/src/util/STL/stdexcept @@ -0,0 +1,110 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2021 - 2022. +// 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) +// + +#ifndef STDEXCEPT_2021_10_22_ + #define STDEXCEPT_2021_10_22_ + + #include + + namespace std + { + class exception + { + public: + exception() noexcept { } + explicit exception(const string&) { } + explicit exception(const char*) { } + + virtual ~exception() { } + + virtual const char* what() const noexcept { static const char pstr[] = "explanatory_string"; return pstr; } + }; + + class logic_error; + class domain_error; + class invalid_argument; + class length_error; + class out_of_range; + class runtime_error; + class range_error; + class overflow_error; + class underflow_error; + + class logic_error : public exception + { + public: + explicit logic_error(const string&) { } + explicit logic_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "logic_error"; return pstr; } + }; + + class domain_error : public exception + { + public: + explicit domain_error(const string&) { } + explicit domain_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "domain_error"; return pstr; } + }; + + class invalid_argument : public exception + { + public: + explicit invalid_argument(const string&) { } + explicit invalid_argument(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "invalid_argument"; return pstr; } + }; + + class length_error : public exception + { + public: + explicit length_error(const string&) { } + explicit length_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "length_error"; return pstr; } + }; + + class out_of_range : public exception + { + public: + explicit out_of_range(const string&) { } + explicit out_of_range(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "out_of_range"; return pstr; } + }; + + class runtime_error : public exception + { + public: + explicit runtime_error(const string&) { } + explicit runtime_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "runtime_error"; return pstr; } + }; + + class range_error : public exception + { + public: + explicit range_error(const string&) { } + explicit range_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "range_error"; return pstr; } + }; + + class overflow_error : public exception + { + public: + explicit overflow_error(const string&) { } + explicit overflow_error(const char*) { } + + virtual const char* what() const noexcept { static const char pstr[] = "overflow_error"; return pstr; } + }; + } + +#endif // STDEXCEPT_2021_10_22_ diff --git a/examples/chapter11_07/src/util/STL/stdfloat b/examples/chapter11_07/src/util/STL/stdfloat new file mode 100644 index 000000000..bfd5f4c65 --- /dev/null +++ b/examples/chapter11_07/src/util/STL/stdfloat @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. +// 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) +// + +#ifndef STDFLOAT_2024_07_12 + #define STDFLOAT_2024_07_12 + + #if defined(__GNUC__) + #pragma GCC system_header + #endif + + namespace std + { + using float32_t = float; + #define __STDCPP_FLOAT32_T__ 1 + + #if (defined(__GNUC__) && defined(__AVR__)) + + #if(__GNUC__ >= 12) + using float64_t = long double; + #define __STDCPP_FLOAT64_T__ 1 + #endif + + #else + + using float64_t = double; + #define __STDCPP_FLOAT64_T__ 1 + + #endif + } + +#endif // STDFLOAT_2024_07_12 diff --git a/examples/chapter11_07/src/util/STL/string b/examples/chapter11_07/src/util/STL/string index 62d7097db..2bda595ba 100644 --- a/examples/chapter11_07/src/util/STL/string +++ b/examples/chapter11_07/src/util/STL/string @@ -19,6 +19,12 @@ { using string = basic_string, allocator>; + // TBD: Implement various forms of to_string (especially for built-in integral types). + inline string to_string(int n) { return std::string(); } + + // TBD: Implement std::string addition. + inline string operator+(const string& a, const string& b) { return std::string(); } + namespace literals { namespace string_literals diff --git a/examples/chapter11_07/src/util/STL/time.h b/examples/chapter11_07/src/util/STL/time.h index 65296a4a2..0bc1d8e84 100644 --- a/examples/chapter11_07/src/util/STL/time.h +++ b/examples/chapter11_07/src/util/STL/time.h @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2022. // 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) diff --git a/examples/chapter11_07/src/util/STL/tuple b/examples/chapter11_07/src/util/STL/tuple index ee82bf9e8..14798e7be 100644 --- a/examples/chapter11_07/src/util/STL/tuple +++ b/examples/chapter11_07/src/util/STL/tuple @@ -8,14 +8,12 @@ #ifndef TUPLE_2010_02_23_ #define TUPLE_2010_02_23_ - #if defined(__GNUC__) - #pragma GCC system_header - #endif - #include #include - #include + #include + #include #include + #include // Implement some of std::tuple for compilers that do not yet support it. // This implementation of tuple supports up to 11 template parameters. @@ -32,18 +30,20 @@ struct xnothing final { - xnothing() { } - xnothing(const xnothing&) { } - ~xnothing() { } - xnothing& operator=(const xnothing&) { return *this; } + constexpr xnothing() = default; + constexpr xnothing(const xnothing&) = default; + constexpr xnothing(xnothing&&) noexcept = default; + ~xnothing() = default; + constexpr auto operator=(const xnothing&) -> xnothing& = default; + constexpr auto operator=(xnothing&&) noexcept -> xnothing& = default; }; - inline bool operator==(const xnothing&, const xnothing&) { return true; } - inline bool operator!=(const xnothing&, const xnothing&) { return false; } - inline bool operator< (const xnothing&, const xnothing&) { return false; } - inline bool operator<=(const xnothing&, const xnothing&) { return false; } - inline bool operator> (const xnothing&, const xnothing&) { return false; } - inline bool operator>=(const xnothing&, const xnothing&) { return false; } + inline constexpr auto operator==(const xnothing&, const xnothing&) noexcept -> bool { return true; } + inline constexpr auto operator!=(const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator< (const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator<=(const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator> (const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator>=(const xnothing&, const xnothing&) noexcept -> bool { return false; } } namespace std @@ -67,6 +67,20 @@ typename T11 = xtuple_helper::xnothing> class tuple { + private: + using type0 = T0; + using type1 = T1; + using type2 = T2; + using type3 = T3; + using type4 = T4; + using type5 = T5; + using type6 = T6; + using type7 = T7; + using type8 = T8; + using type9 = T9; + using type10 = T10; + using type11 = T11; + public: template @@ -75,63 +89,67 @@ template friend class xtuple_helper::xsize; - typedef tuple tuple_type; - - tuple() { } - - explicit tuple(const T0& p0, - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10(), - const T11& p11 = T11()) : t0 (p0), - t1 (p1), - t2 (p2), - t3 (p3), - t4 (p4), - t5 (p5), - t6 (p6), - t7 (p7), - t8 (p8), - t9 (p9), - t10(p10), - t11(p11){ } - - tuple(const tuple_type& t) : t0 (t.t0), - t1 (t.t1), - t2 (t.t2), - t3 (t.t3), - t4 (t.t4), - t5 (t.t5), - t6 (t.t6), - t7 (t.t7), - t8 (t.t8), - t9 (t.t9), - t10(t.t10), - t11(t.t11){ } + using tuple_type = tuple; + + constexpr tuple() = default; + + constexpr tuple(const T0& p0, + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10(), + const T11& p11 = T11()) : t0 (p0), + t1 (p1), + t2 (p2), + t3 (p3), + t4 (p4), + t5 (p5), + t6 (p6), + t7 (p7), + t8 (p8), + t9 (p9), + t10(p10), + t11(p11) { } + + constexpr tuple(const tuple_type& t) : t0 (t.t0), + t1 (t.t1), + t2 (t.t2), + t3 (t.t3), + t4 (t.t4), + t5 (t.t5), + t6 (t.t6), + t7 (t.t7), + t8 (t.t8), + t9 (t.t9), + t10(t.t10), + t11(t.t11) { } + + constexpr tuple(tuple_type&& t) noexcept + : t0 (t.t0), + t1 (t.t1), + t2 (t.t2), + t3 (t.t3), + t4 (t.t4), + t5 (t.t5), + t6 (t.t6), + t7 (t.t7), + t8 (t.t8), + t9 (t.t9), + t10(t.t10), + t11(t.t11) { } template - tuple(const std::pair& p) : t0 (p.first), - t1 (p.second), - t2 (T2 ()), - t3 (T3 ()), - t4 (T4 ()), - t5 (T5 ()), - t6 (T6 ()), - t7 (T7 ()), - t8 (T8 ()), - t9 (T9 ()), - t10(T10()), - t11(T11()){ } - - ~tuple() { } + constexpr tuple(const std::pair& p) : t0 (p.first), + t1 (p.second) { } + + ~tuple() = default; template - tuple& operator=(const tuple& t) + constexpr tuple& operator=(const tuple& t) + { + if(this != &t) + { + t0 = T0 (t.t0); + t1 = T1 (t.t1); + t2 = T2 (t.t2); + t3 = T3 (t.t3); + t4 = T4 (t.t4); + t5 = T5 (t.t5); + t6 = T6 (t.t6); + t7 = T7 (t.t7); + t8 = T8 (t.t8); + t9 = T9 (t.t9); + t10 = T10(t.t10); + t11 = T11(t.t11); + } + + return *this; + } + + constexpr tuple& operator=(tuple&& t) noexcept { - t0 = T0 (t.t0); - t1 = T1 (t.t1); - t2 = T2 (t.t2); - t3 = T3 (t.t3); - t4 = T4 (t.t4); - t5 = T5 (t.t5); - t6 = T6 (t.t6); - t7 = T7 (t.t7); - t8 = T8 (t.t8); - t9 = T9 (t.t9); - t10 = T10(t.t10); - t11 = T11(t.t11); + t0 = static_cast(t.t0); + t1 = static_cast(t.t1); + t2 = static_cast(t.t2); + t3 = static_cast(t.t3); + t4 = static_cast(t.t4); + t5 = static_cast(t.t5); + t6 = static_cast(t.t6); + t7 = static_cast(t.t7); + t8 = static_cast(t.t8); + t9 = static_cast(t.t9); + t10 = static_cast(t.t10); + t11 = static_cast(t.t11); return *this; } template - tuple& operator=(const std::pair& p) + constexpr tuple& operator=(const std::pair& p) { t0 = T0 (p.first); t1 = T1 (p.second); @@ -183,51 +222,75 @@ return *this; } - void swap(tuple& other) + constexpr void swap(tuple& other) { if(this != &other) { - const type0 tmp0 (t0 ); t0 = other.t0 ; other.t0 = tmp0 ; - const type1 tmp1 (t1 ); t1 = other.t1 ; other.t1 = tmp1 ; - const type2 tmp2 (t2 ); t2 = other.t2 ; other.t2 = tmp2 ; - const type3 tmp3 (t3 ); t3 = other.t3 ; other.t3 = tmp3 ; - const type4 tmp4 (t4 ); t4 = other.t4 ; other.t4 = tmp4 ; - const type5 tmp5 (t5 ); t5 = other.t5 ; other.t5 = tmp5 ; - const type6 tmp6 (t6 ); t6 = other.t6 ; other.t6 = tmp6 ; - const type7 tmp7 (t7 ); t7 = other.t7 ; other.t7 = tmp7 ; - const type8 tmp8 (t8 ); t8 = other.t8 ; other.t8 = tmp8 ; - const type9 tmp9 (t9 ); t9 = other.t9 ; other.t9 = tmp9 ; - const type10 tmp10(t10); t10 = other.t10; other.t10 = tmp10; - const type11 tmp11(t11); t11 = other.t11; other.t11 = tmp11; + my_swap(t0 , other.t0); + my_swap(t1 , other.t1); + my_swap(t2 , other.t2); + my_swap(t3 , other.t3); + my_swap(t4 , other.t4); + my_swap(t5 , other.t5); + my_swap(t6 , other.t6); + my_swap(t7 , other.t7); + my_swap(t8 , other.t8); + my_swap(t9 , other.t9); + my_swap(t10, other.t10); + my_swap(t11, other.t11); } } + constexpr void swap(tuple&& other) + { + my_swap(static_cast(t0) , static_cast(other.t0)); + my_swap(static_cast(t1) , static_cast(other.t1)); + my_swap(static_cast(t2) , static_cast(other.t2)); + my_swap(static_cast(t3) , static_cast(other.t3)); + my_swap(static_cast(t4) , static_cast(other.t4)); + my_swap(static_cast(t5) , static_cast(other.t5)); + my_swap(static_cast(t6) , static_cast(other.t6)); + my_swap(static_cast(t7) , static_cast(other.t7)); + my_swap(static_cast(t8) , static_cast(other.t8)); + my_swap(static_cast(t9) , static_cast(other.t9)); + my_swap(static_cast(t10), static_cast(other.t10)); + my_swap(static_cast(t11), static_cast(other.t11)); + } + private: - T0 t0; - T1 t1; - T2 t2; - T3 t3; - T4 t4; - T5 t5; - T6 t6; - T7 t7; - T8 t8; - T9 t9; - T10 t10; - T11 t11; - - typedef T0 type0; - typedef T1 type1; - typedef T2 type2; - typedef T3 type3; - typedef T4 type4; - typedef T5 type5; - typedef T6 type6; - typedef T7 type7; - typedef T8 type8; - typedef T9 type9; - typedef T10 type10; - typedef T11 type11; + type0 t0 { }; + type1 t1 { }; + type2 t2 { }; + type3 t3 { }; + type4 t4 { }; + type5 t5 { }; + type6 t6 { }; + type7 t7 { }; + type8 t8 { }; + type9 t9 { }; + type10 t10 { }; + type11 t11 { }; + + template + constexpr void my_swap(swap_type& left, swap_type& right) + { + if(&left != &right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } + } + + template + constexpr void my_swap(swap_type&& left, swap_type&& right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } }; } @@ -236,14 +299,14 @@ template class xget { }; - #define MAKE_XTUPLE_GET_HELPER(NUM) \ - template class xget<(NUM), xtuple_type> \ - { \ - public: \ - typedef typename xtuple_type::type##NUM xelem_type; \ - static xelem_type& get ( xtuple_type& t) { return t.t##NUM ; } \ - static const xelem_type& get_const(const xtuple_type& t) { return t.t##NUM ; } \ - } \ + #define MAKE_XTUPLE_GET_HELPER(NUM) \ + template class xget<(NUM), xtuple_type> \ + { \ + public: \ + typedef typename xtuple_type::type##NUM xelem_type; \ + static constexpr xelem_type& get ( xtuple_type& t) { return t.t##NUM ; } \ + static constexpr const xelem_type& get_const(const xtuple_type& t) { return t.t##NUM ; } \ + } MAKE_XTUPLE_GET_HELPER(0); MAKE_XTUPLE_GET_HELPER(1); @@ -265,76 +328,76 @@ class xsize { public: - static STL_LOCAL_CONSTEXPR std::size_t value = xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value; + static constexpr std::size_t value = xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value; }; } namespace std { template - typename xtuple_helper::xget >::xelem_type& get(tuple<>& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple<>& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple<>& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple<>& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template @@ -372,7 +435,7 @@ class tuple_size { public: - static STL_LOCAL_CONSTEXPR std::size_t value = xtuple_helper::xsize::value; + static constexpr std::size_t value = xtuple_helper::xsize::value; }; template @@ -385,31 +448,31 @@ class tuple_size : public std::integral_constant::value> { }; template - tuple make_tuple(const T0& p0 = T0 ()) + constexpr tuple make_tuple(const T0& p0 = T0 ()) { return tuple(p0); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 ()) { return tuple(p0, p1); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 ()) { return tuple(p0, p1, p2); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 ()) { return tuple(p0, p1, p2, p3); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 ()) { return tuple(p0, p1, p2, p3, p4); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 ()) { return tuple(p0, p1, p2, p3, p4, p5); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10(), - const T11& p11 = T11()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10(), + const T11& p11 = T11()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } } + namespace xtuple_helper + { + struct ignore_t + { + template + constexpr ignore_t& operator=(T&&) noexcept { return *this; } + + template + constexpr ignore_t& operator=(ignore_t&&) noexcept { return *this; } + }; + } + + namespace std + { + constexpr xtuple_helper::ignore_t ignore; + + template + constexpr std::tuple tie(Args&... args) noexcept + { + return {args...}; + } + } + #endif // TUPLE_2010_02_23_ diff --git a/examples/chapter11_07/src/util/STL/type_traits b/examples/chapter11_07/src/util/STL/type_traits index 25f0a4147..7c9d8caa4 100644 --- a/examples/chapter11_07/src/util/STL/type_traits +++ b/examples/chapter11_07/src/util/STL/type_traits @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2013 - 2022. // 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) @@ -9,9 +9,7 @@ #define TYPE_TRAITS_2013_09_01_ #include - - #include - #include + #include // Implement some of for compilers that do not yet support it. @@ -23,11 +21,11 @@ { typedef the_value_type value_type; - static STL_LOCAL_CONSTEXPR value_type value = the_value; + static constexpr value_type value = the_value; typedef integral_constant type; - STL_LOCAL_CONSTEXPR operator value_type() const STL_LOCAL_NOEXCEPT + constexpr operator value_type() const { return value; } @@ -93,6 +91,11 @@ typedef false_type type; }; + template + using conditional_t = typename conditional::type; + template struct is_same : false_type { }; @@ -138,6 +141,12 @@ template struct is_array : std::true_type {}; + template struct is_reference : std::false_type { }; + template struct is_reference : std::true_type { }; + template struct is_reference : std::true_type { }; + + template struct is_function : std::integral_constant::value && !std::is_reference::value> { }; + template using remove_cv_t = typename remove_cv::type; template using remove_const_t = typename remove_const::type; template using remove_volatile_t = typename remove_volatile::type; @@ -153,6 +162,39 @@ template using remove_cvref_t = typename remove_cvref::type; + + template + constexpr remove_reference_t&& move(T&& arg) + { + return static_cast&&>(arg); + } + } + + namespace std + { + template + struct make_unsigned + { + using type = typename std::conditional<(sizeof(T) > 4U), std::uint64_t, + typename std::conditional<(sizeof(T) > 2U), std::uint32_t, + typename std::conditional<(sizeof(T) > 1U), std::uint16_t, + std::uint8_t>::type>::type>::type; + }; + + template + struct make_signed + { + using type = typename std::conditional<(sizeof(T) > 4U), std::int64_t, + typename std::conditional<(sizeof(T) > 2U), std::int32_t, + typename std::conditional<(sizeof(T) > 1U), std::int16_t, + std::int8_t>::type>::type>::type; + }; + + template + using make_unsigned_t = typename std::make_unsigned::type; + + template + using make_signed_t = typename std::make_signed::type; } namespace traits_helper @@ -178,20 +220,37 @@ namespace traits_helper { - template + template struct type_identity { using type = T; }; - template + template auto try_add_lvalue_reference(int) -> type_identity; - template + template auto try_add_lvalue_reference(...) -> type_identity; - template + template auto try_add_rvalue_reference(int) -> type_identity; - template + template auto try_add_rvalue_reference(...) -> type_identity; + + template + std::integral_constant test(int T::*); + + template + std::false_type test(...); + + template + std::true_type test_pre_ptr_convertible(const volatile B*); + template + std::false_type test_pre_ptr_convertible(const volatile void*); + + template + auto test_pre_is_base_of(...) -> std::true_type; + template + auto test_pre_is_base_of(int) -> + decltype(test_pre_ptr_convertible(static_cast(nullptr))); } namespace std @@ -204,6 +263,242 @@ template typename std::add_rvalue_reference::type declval(); + + template + struct is_class : decltype(traits_helper::test(nullptr)) { }; + + template + struct is_base_of : std::integral_constant::value && std::is_class::value && + decltype(traits_helper::test_pre_is_base_of(0))::value> { }; + + template + struct remove_extent { typedef T type; }; + + template + struct remove_extent { typedef T type; }; + + template + struct remove_extent { typedef T type; }; + + template< class T > + struct decay + { + private: + typedef typename std::remove_reference::type U; + + public: + typedef typename std::conditional::value, + typename std::remove_extent::type*, + typename std::conditional::value, + typename std::add_pointer::type, + typename std::remove_cv::type>::type>::type type; + }; + + template + using void_t = void; + + // primary template (used for zero types) + template + struct common_type { }; + + // 1 type + template + struct common_type : common_type {}; + + // 2 types + template + using cond_t = decltype(false ? std::declval() : std::declval()); + + template + struct common_type_2_impl {}; + + template + struct common_type_2_impl>> + { + using type = typename std::decay>::type; + }; + + template + struct common_type : common_type_2_impl::type, + typename std::decay::type> { }; + + // 3 or more types + template + struct common_type_multi_impl { }; + + template + struct common_type_multi_impl::type>, T1, T2, R...> + : common_type::type, R...> { }; + + template + struct common_type : common_type_multi_impl {}; + } + + #if(__cplusplus >= 201703L) + // C++17 and later + namespace std + { + template + inline constexpr bool is_same_v = is_same::value; + + template + inline constexpr bool is_integral_v = is_integral::value; + + template + inline constexpr bool is_floating_point_v = is_floating_point::value; + + template< class Base, class Derived > + inline constexpr bool is_base_of_v = is_base_of::value; + } + #endif + + #if(__cplusplus > 202002L) + // C++20 and later + namespace std + { + template + struct type_identity + { + using type = T; + }; + + template + using type_identity_t = typename type_identity::type; + } + #endif + + namespace traits_helper + { + template + auto test_returnable(int) -> + decltype + ( + void(static_cast(nullptr)), std::true_type { } + ); + + template + auto test_returnable(...) -> std::false_type; + + template + auto test_implicitly_convertible(int) -> + decltype + ( + void(std::declval()(std::declval())), std::true_type { } + ); + + template + auto test_implicitly_convertible(...) -> std::false_type; + + typedef char yes_type; + + struct no_type + { + char padding[8]; + }; + + struct is_constructible_imp + { + template()...))> + static traits_helper::yes_type test(int); + template + static traits_helper::no_type test(...); + + template()))> + static traits_helper::yes_type test1(int); + template + static traits_helper::no_type test1(...); + + template + static traits_helper::yes_type ref_test(T); + template + static traits_helper::no_type ref_test(...); + }; + + template + struct ok_tag { double d; char c[N]; }; + + template + ok_tag check_is_complete(int); + + template + char check_is_complete(...); + + struct is_default_constructible_imp + { + template + static traits_helper::yes_type test(int); + + template + static traits_helper::no_type test(...); + }; + + struct is_destructible_imp + { + template().~T())> + static traits_helper::yes_type test(int); + template + static traits_helper::no_type test(...); + }; + } + + namespace std + { + template struct is_complete + : public std::integral_constant::type>::value + || (sizeof(traits_helper::check_is_complete(0)) != sizeof(char))> { }; + + template struct is_destructible + : public std::integral_constant(0)) == sizeof(traits_helper::yes_type)> + { + static_assert(std::is_complete::value, "Arguments to is_destructible must be complete types"); + }; + + template struct is_default_constructible + : public integral_constant(0)) == sizeof(traits_helper::yes_type)> + { + static_assert(std::is_complete::value, "Arguments to is_default_constructible must be complete types"); + }; + + template struct is_default_constructible : public is_default_constructible{}; + template struct is_default_constructible : public is_default_constructible{}; + template struct is_default_constructible : public integral_constant{}; + + template struct is_default_constructible : public integral_constant{}; + + template <> struct is_default_constructible : public integral_constant{}; + template <> struct is_default_constructible : public integral_constant{}; + template <> struct is_default_constructible : public integral_constant{}; + template <> struct is_default_constructible : public integral_constant{}; + + template + struct is_convertible + : std::integral_constant(0))::value + && decltype(traits_helper::test_implicitly_convertible(0))::value) + || (std::is_void::value && std::is_void::value)> { }; + + template struct is_constructible + : public std::integral_constant(0)) == sizeof(traits_helper::yes_type)> + { + static_assert(std::is_complete::value, "The target type must be complete in order to test for constructibility"); + }; + + template struct is_constructible : public integral_constant::value && sizeof(traits_helper::is_constructible_imp::test1(0)) == sizeof(traits_helper::yes_type)> + { + static_assert(std::is_complete::value, "The target type must be complete in order to test for constructibility"); + }; + + template struct is_constructible : public integral_constant (std::declval())) == sizeof(traits_helper::yes_type)> { }; + template struct is_constructible : public integral_constant(std::declval())) == sizeof(traits_helper::yes_type)> { }; + + template <> struct is_constructible : public false_type { }; + template <> struct is_constructible : public false_type { }; + template <> struct is_constructible : public false_type { }; + template <> struct is_constructible : public false_type { }; + + template struct is_constructible : public is_default_constructible { }; } #endif // TYPE_TRAITS_2013_09_01_ diff --git a/examples/chapter11_07/src/util/STL/utility b/examples/chapter11_07/src/util/STL/utility index 55ecf320e..376d858c5 100644 --- a/examples/chapter11_07/src/util/STL/utility +++ b/examples/chapter11_07/src/util/STL/utility @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2023. // 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) @@ -10,6 +10,7 @@ #include #include + #include // Implement some of for compilers that do not yet support it. @@ -18,16 +19,22 @@ // Forward declaration of std::identity, which is implemented in . template struct identity; - } - namespace std - { - template - T&& forward(typename identity::type& param) + template + constexpr T&& forward(remove_reference_t& arg) STL_LOCAL_NOEXCEPT { - return static_cast(param); + return static_cast(arg); } + template + constexpr T&& forward(remove_reference_t&& arg) STL_LOCAL_NOEXCEPT + { + return static_cast(arg); + } + } + + namespace std + { template class pair @@ -47,10 +54,32 @@ pair(const pair& other) : first (other.first), second(other.second) { } + pair(pair&& other) noexcept : first (other.first), + second(other.second) { } + template pair(const pair& p) : first (T1(p.first)), second(T2(p.second)) { } + + pair& operator=(const pair& other) + { + if(*this != &other) + { + first = other.first; + second = other.second; + } + + return *this; + } + + pair& operator=(pair&& other) noexcept + { + first = other.first; + second = other.second; + + return *this; + } }; } @@ -164,13 +193,13 @@ template bool operator<=(const std::pair& left, const std::pair& right) { - return ((right < left) == false); + return (!(right < left)); } template bool operator>=(const std::pair& left, const std::pair& right) { - return ((left < right) == false); + return (!(left < right)); } template diff --git a/examples/chapter11_07/src/util/STL/version b/examples/chapter11_07/src/util/STL/version new file mode 100644 index 000000000..5ba3311be --- /dev/null +++ b/examples/chapter11_07/src/util/STL/version @@ -0,0 +1,16 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. +// 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) +// + +#ifndef VERSION_2024_06_29 + #define VERSION_2024_06_29 + + // Implement some of for compilers that do not yet support it. + // In this particular case, simply include the standard ISO header. + + #include + +#endif // VERSION_2024_06_29 diff --git a/examples/chapter11_07/src/util/STL_C++XX_stdfloat/cstdfloat b/examples/chapter11_07/src/util/STL_C++XX_stdfloat/cstdfloat index ece28d13a..c060f0845 100644 --- a/examples/chapter11_07/src/util/STL_C++XX_stdfloat/cstdfloat +++ b/examples/chapter11_07/src/util/STL_C++XX_stdfloat/cstdfloat @@ -14,7 +14,7 @@ #ifndef CSTDFLOAT_2014_01_09_ #define CSTDFLOAT_2014_01_09_ - #include + #include "stdfloat.h" #include // Here, we define floating-point typedefs having specified widths @@ -30,7 +30,7 @@ using ::float_fast16_t; using ::float_least16_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 11) && (std::numeric_limits::max_exponent == 16), @@ -42,7 +42,7 @@ using ::float_fast32_t; using ::float_least32_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 24) && (std::numeric_limits::max_exponent == 128), @@ -54,7 +54,7 @@ using ::float_fast64_t; using ::float_least64_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 53) && (std::numeric_limits::max_exponent == 1024), @@ -66,7 +66,7 @@ using ::float_fast80_t; using ::float_least80_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 64) && (std::numeric_limits::max_exponent == 16384), @@ -78,7 +78,7 @@ using ::float_fast128_t; using ::float_least128_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 113) && (std::numeric_limits::max_exponent == 16384), diff --git a/examples/chapter11_07/src/util/memory/util_factory.h b/examples/chapter11_07/src/util/memory/util_factory.h index 1def4c7bf..758413a62 100644 --- a/examples/chapter11_07/src/util/memory/util_factory.h +++ b/examples/chapter11_07/src/util/memory/util_factory.h @@ -1,72 +1,81 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_FACTORY_2012_02_19_H_ - #define UTIL_FACTORY_2012_02_19_H_ +#ifndef UTIL_FACTORY_2012_02_19_H + #define UTIL_FACTORY_2012_02_19_H + #include + #include #include - #include - namespace util { - class factory_product : private util::noncopyable + class factory_product { public: virtual ~factory_product() { } - virtual void init() = 0; + virtual auto init() -> void = 0; protected: factory_product() { } }; template> + typename AllocatorType = std::allocator> class factory { public: - typedef T value_type; - typedef T* pointer_type; - typedef alloc allocator_type; + using value_type = T; + using pointer_type = T*; + using allocator_type = AllocatorType; - static pointer_type make() + static auto make() -> pointer_type { pointer_type p = new(allocate()) value_type(); + static_cast(p)->init(); + return p; } template - static pointer_type make(parameters... params) + static auto make(parameters... params) -> pointer_type { pointer_type p = new(allocate()) value_type(params...); + static_cast(p)->init(); + return p; } private: - static void* allocate() + static auto allocate() -> void* { - return allocator_type().allocate(1U, nullptr); + return allocator_type().allocate( std::size_t { UINT8_C(1) } ); } }; } -#endif // UTIL_FACTORY_2012_02_19_H_ +#endif // UTIL_FACTORY_2012_02_19_H /* + +// See also link at GodBolt: https://godbolt.org/z/WrTTa8Eq9 + #include +#include + class something : public util::factory_product { public: - something() { } - virtual ~something() { } + something() = default; + virtual ~something() = default; private: virtual void init() { } @@ -75,18 +84,31 @@ class something : public util::factory_product class another : public util::factory_product { public: - another(const int m, const int n) : my_m(m), - my_n(n) { } + explicit another(const int m = 0, const int n = 0) + : my_m(m), + my_n(n) { } + + ~another() override = default; - virtual ~another() { } + auto get_m() const -> int { return my_m; } + auto get_n() const -> int { return my_n; } private: - const int my_m; - const int my_n; + const int my_m { }; + const int my_n { }; - virtual void init() { } + auto init() -> void override { } }; -something* p_something = util::factory::make(); -another* p_another = util::factory::make(123, 456); +auto main() -> int +{ + something* p_something = util::factory::make(); + another* p_another = util::factory::make(123, 456); + + std::cout << p_another->get_n() << '\n'; + std::cout << p_another->get_m() << std::endl; + + delete p_something; + delete p_another; +} */ diff --git a/examples/chapter11_07/src/util/memory/util_n_slot_array_allocator.h b/examples/chapter11_07/src/util/memory/util_n_slot_array_allocator.h new file mode 100644 index 000000000..37b9b382b --- /dev/null +++ b/examples/chapter11_07/src/util/memory/util_n_slot_array_allocator.h @@ -0,0 +1,195 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2020 - 2024. +// 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) +// + +#ifndef UTIL_N_SLOT_ARRAY_ALLOCATOR_2020_10_25_H // NOLINT(llvm-header-guard) + #define UTIL_N_SLOT_ARRAY_ALLOCATOR_2020_10_25_H + + #include + #include + #include + #include + + namespace util { + + // Forward declaration of n_slot_array_allocator template. + template + class n_slot_array_allocator; + + // Template partial specialization of n_slot_array_allocator template for void. + template + class n_slot_array_allocator + { + public: + using value_type = void; + using pointer = value_type*; + using const_pointer = const value_type*; + + template + struct rebind + { + using other = n_slot_array_allocator; + }; + }; + + template + class n_slot_array_allocator // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) + { + private: + static constexpr std::uint_fast32_t slot_width = SlotWidth; + static constexpr std::size_t slot_count = SlotCount; + + using slot_array_type = std::array; + using slot_array_memory_type = std::array; + using slot_array_flags_type = std::array; + + public: + using size_type = std::size_t; + using value_type = typename slot_array_type::value_type; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + + constexpr n_slot_array_allocator() = default; // LCOV_EXCL_LINE + + constexpr n_slot_array_allocator(const n_slot_array_allocator&) = default; // LCOV_EXCL_LINE + + template + struct rebind + { + using other = n_slot_array_allocator; + }; + + constexpr auto max_size() const noexcept -> size_type { return slot_count; } + + constexpr auto address( reference x) const -> pointer { return &x; } + constexpr auto address(const_reference x) const -> const_pointer { return &x; } + + auto allocate(size_type count, const_pointer p_hint = nullptr) -> pointer + { + static_cast(count); + static_cast(p_hint); + + pointer p { nullptr }; + + // TBD: There is most likely significant optimization potential + // capable of being unlocked if a storage/lookup mechanism can be + // devised that uses a binary search when finding the next free slot. + + // (TBD) In fact, constant-time allocation probably possible, as shown in: + // SmallObjectAllocator from Modern C++ Design by Andrei Alexandrescu. + + for(auto i = static_cast(UINT8_C(0)); i < slot_count; ++i) + { + using local_flags_value_type = typename slot_array_flags_type::value_type; + + if(slot_flags[i] == static_cast(UINT8_C(0))) // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + { + slot_flags[i] = static_cast(UINT8_C(1)); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + + p = static_cast(slot_array_memory[i].data()); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + + if(i > slot_max_index) + { + slot_max_index = i; + + static_cast(slot_max_index); + } + + break; + } + } + + return p; + } + + auto construct(pointer p, const value_type& x) -> void + { + // The memory in the n-slot allocator already exists + // in an uninitialized form. Construction can safely + // simply set the value in the uninitialized memory. + + *p = x; + } + + auto destroy(pointer p) const -> void { static_cast(p); } // LCOV_EXCL_LINE + + auto deallocate(pointer p_slot, size_type sz) -> void + { + static_cast(sz); + + typename slot_array_memory_type::size_type index { }; + + for(auto& slot_array_memory_entry : slot_array_memory) + { + if(p_slot == static_cast(slot_array_memory_entry.data())) + { + using local_flags_value_type = typename slot_array_flags_type::value_type; + + slot_flags[index] = static_cast(UINT8_C(0)); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + + break; + } + + ++index; + } + } + + private: + static slot_array_memory_type slot_array_memory; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + static slot_array_flags_type slot_flags; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + static std::size_t slot_max_index; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + }; + + template + typename n_slot_array_allocator::slot_array_memory_type n_slot_array_allocator::slot_array_memory; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables,hicpp-uppercase-literal-suffix,readability-uppercase-literal-suffix) + + template + typename n_slot_array_allocator::slot_array_flags_type n_slot_array_allocator::slot_flags; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables,hicpp-uppercase-literal-suffix,readability-uppercase-literal-suffix) + + template + std::size_t n_slot_array_allocator::slot_max_index; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables,hicpp-uppercase-literal-suffix,readability-uppercase-literal-suffix) + + // Global comparison operators (required by the standard). + template + auto operator==(const n_slot_array_allocator& left, + const n_slot_array_allocator& right) -> bool + { + static_cast(left.max_size()); + static_cast(right.max_size()); + + return true; + } + + template + auto operator!=(const n_slot_array_allocator& left, + const n_slot_array_allocator& right) -> bool + { + static_cast(left.max_size()); + static_cast(right.max_size()); + + return false; + } + + } // namespace util + +#endif // UTIL_N_SLOT_ARRAY_ALLOCATOR_2020_10_25_H diff --git a/examples/chapter11_07/src/util/memory/util_placed_pointer.h b/examples/chapter11_07/src/util/memory/util_placed_pointer.h index 308889925..bc933ca3b 100644 --- a/examples/chapter11_07/src/util/memory/util_placed_pointer.h +++ b/examples/chapter11_07/src/util/memory/util_placed_pointer.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2020. // 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) diff --git a/examples/chapter11_07/src/util/memory/util_ring_allocator.h b/examples/chapter11_07/src/util/memory/util_ring_allocator.h index 8465ac4ed..7a3a48ef1 100644 --- a/examples/chapter11_07/src/util/memory/util_ring_allocator.h +++ b/examples/chapter11_07/src/util/memory/util_ring_allocator.h @@ -1,26 +1,26 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2017. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_RING_ALLOCATOR_2010_02_23_H_ - #define UTIL_RING_ALLOCATOR_2010_02_23_H_ +#ifndef UTIL_RING_ALLOCATOR_2010_02_23_H + #define UTIL_RING_ALLOCATOR_2010_02_23_H + + #include #include #include #include - #include - namespace util { class ring_allocator_base { public: - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; virtual ~ring_allocator_base() = default; @@ -32,7 +32,7 @@ // The ring allocator's buffer type. struct buffer_type { - static constexpr size_type size = 16U; + static constexpr size_type size = 64U; std::uint8_t data[size]; @@ -41,7 +41,7 @@ // The ring allocator's memory allocation. template - static void* do_allocate(size_type chunk_size) + static auto do_allocate(size_type chunk_size) -> void* { ALIGNAS(16) static buffer_type buffer; @@ -80,14 +80,14 @@ }; // Global comparison operators (required by the standard). - inline bool operator==(const ring_allocator_base&, - const ring_allocator_base&) noexcept + inline auto operator==(const ring_allocator_base&, + const ring_allocator_base&) noexcept -> bool { return true; } - inline bool operator!=(const ring_allocator_base&, - const ring_allocator_base&) noexcept + inline auto operator!=(const ring_allocator_base&, + const ring_allocator_base&) noexcept -> bool { return false; } @@ -100,9 +100,9 @@ class ring_allocator : public ring_allocator_base { public: - typedef void value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; + using value_type = void; + using pointer = value_type*; + using const_pointer = const value_type*; template struct rebind @@ -119,11 +119,11 @@ static_assert(sizeof(T) <= buffer_type::size, "The size of the allocation object can not exceed the buffer size."); - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; + using value_type = T; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; ring_allocator() noexcept = default; @@ -138,16 +138,16 @@ using other = ring_allocator; }; - size_type max_size() const noexcept + auto max_size() const noexcept -> size_type { return buffer_type::size / sizeof(value_type); } - pointer address( reference x) const { return &x; } - const_pointer address(const_reference x) const { return &x; } + auto address( reference x) const -> pointer { return &x; } + auto address(const_reference x) const -> const_pointer { return &x; } - pointer allocate(size_type count, - typename ring_allocator::const_pointer = nullptr) + auto allocate(size_type count, + typename ring_allocator::const_pointer = nullptr) -> pointer { const size_type chunk_size = count * sizeof(value_type); @@ -156,15 +156,15 @@ return static_cast(p); } - void construct(pointer p, const value_type& x) noexcept + auto construct(pointer p, const value_type& x) noexcept -> void { new(static_cast(p)) value_type(x); } - void destroy(pointer p) noexcept { p->~value_type(); } + auto destroy(pointer p) noexcept -> void { p->~value_type(); } - void deallocate(pointer, size_type) noexcept { } + auto deallocate(pointer, size_type) noexcept -> void { } }; } -#endif // UTIL_RING_ALLOCATOR_2010_02_23_H_ +#endif // UTIL_RING_ALLOCATOR_2010_02_23_H diff --git a/examples/chapter11_07/src/util/memory/util_static_allocator.h b/examples/chapter11_07/src/util/memory/util_static_allocator.h index 4ad4ad07a..62b83e148 100644 --- a/examples/chapter11_07/src/util/memory/util_static_allocator.h +++ b/examples/chapter11_07/src/util/memory/util_static_allocator.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2017. +// Copyright Christopher Kormanyos 2007 - 2021. // 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) @@ -31,7 +31,7 @@ // The static allocator's buffer type. struct buffer_type { - static constexpr size_type size = 16U; + static constexpr size_type size = 640U; std::uint8_t data[size]; diff --git a/examples/chapter11_07/src/util/safety/memory/util_safety_rom_memory_checksum.h b/examples/chapter11_07/src/util/safety/memory/util_safety_rom_memory_checksum.h index 32d52ce41..637f1c93f 100644 --- a/examples/chapter11_07/src/util/safety/memory/util_safety_rom_memory_checksum.h +++ b/examples/chapter11_07/src/util/safety/memory/util_safety_rom_memory_checksum.h @@ -5,6 +5,7 @@ #include #include + #include #include #include @@ -72,10 +73,10 @@ const std::size_t memory_list_count> void util::safety::rom_memory_checksum::finalize() { - const std::uint8_t expected_result_byte0 = mcal::cpu::read_program_memory(reinterpret_cast(address_of_result + 3U)); - const std::uint8_t expected_result_byte1 = mcal::cpu::read_program_memory(reinterpret_cast(address_of_result + 2U)); - const std::uint8_t expected_result_byte2 = mcal::cpu::read_program_memory(reinterpret_cast(address_of_result + 1U)); - const std::uint8_t expected_result_byte3 = mcal::cpu::read_program_memory(reinterpret_cast(address_of_result + 0U)); + const std::uint8_t expected_result_byte0 = mcal::memory::progmem::read(address_of_result + 3U); + const std::uint8_t expected_result_byte1 = mcal::memory::progmem::read(address_of_result + 2U); + const std::uint8_t expected_result_byte2 = mcal::memory::progmem::read(address_of_result + 1U); + const std::uint8_t expected_result_byte3 = mcal::memory::progmem::read(address_of_result + 0U); const std::uint32_t expected_result = util::make_long(util::make_long(expected_result_byte0, expected_result_byte1), diff --git a/examples/chapter11_07/src/util/utility/util_alignas.h b/examples/chapter11_07/src/util/utility/util_alignas.h index 0cd13a5a7..c933895fc 100644 --- a/examples/chapter11_07/src/util/utility/util_alignas.h +++ b/examples/chapter11_07/src/util/utility/util_alignas.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2020. // 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) diff --git a/examples/chapter11_07/src/util/utility/util_baselexical_cast.h b/examples/chapter11_07/src/util/utility/util_baselexical_cast.h new file mode 100644 index 000000000..16f64a655 --- /dev/null +++ b/examples/chapter11_07/src/util/utility/util_baselexical_cast.h @@ -0,0 +1,173 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2020 - 2024. +// 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) +// + +#ifndef UTIL_BASELEXICAL_CAST_2020_06_28_H // NOLINT(llvm-header-guard) + #define UTIL_BASELEXICAL_CAST_2020_06_28_H + + #if ((defined(__cplusplus) && (__cplusplus >= 201703L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) + #if !(defined(__GNUC__) && defined(__AVR__)) + #define UTIL_BASELEXICAL_CAST_HAS_CHARCONV + #endif + #endif + + #if defined(UTIL_BASELEXICAL_CAST_HAS_CHARCONV) + #include + #include + #else + #include + #include + #include + #include + #endif + + namespace util { + + #if defined(UTIL_BASELEXICAL_CAST_HAS_CHARCONV) + + template(UINT8_C(10)), + const bool UpperCase = true> + auto baselexical_cast(const UnsignedIntegerType& u, char* first, char* last) -> const char* + { + constexpr auto my_base = static_cast(BaseRepresentation); + + const auto result = std::to_chars(first, last, u, my_base); + + return result.ptr; + } + + #else + + template + struct baselexical_cast_helper + { + private: + using output_value_type = typename std::iterator_traits::value_type; + + public: + static auto extract(output_value_type) noexcept -> output_value_type = delete; + }; + + template + struct baselexical_cast_helper(UINT8_C(16))> + { + private: + using output_value_type = typename std::iterator_traits::value_type; + + public: + static auto extract(output_value_type c) noexcept -> output_value_type + { + if(c <= static_cast(INT8_C(9))) + { + c = + static_cast + ( + c + static_cast('0') + ); + } + else if((c >= static_cast(0xA)) && (c <= static_cast(INT8_C(0xF)))) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) + { + c = + static_cast + ( + static_cast(UpperCase ? static_cast('A') : static_cast('a')) + + static_cast(c - static_cast(INT8_C(0xA))) + ); + } + + return c; + } + }; + + template + struct baselexical_cast_helper(UINT8_C(10))> + { + private: + using output_value_type = typename std::iterator_traits::value_type; + + public: + static auto extract(output_value_type c) noexcept -> output_value_type + { + if(c <= static_cast(INT8_C(9))) + { + c = + static_cast + ( + c + static_cast('0') + ); + } + + return c; + } + }; + + template(UINT8_C(10)), + const bool UpperCase = true> + auto baselexical_cast(const UnsignedIntegerType& u, OutputIterator out, OutputIterator out_dummy) -> OutputIterator + { + static_cast(out_dummy); + + using unsigned_integer_type = UnsignedIntegerType; + using output_value_type = typename std::iterator_traits::value_type; + + if(u == static_cast(UINT8_C(0))) + { + *out = + static_cast + ( + baselexical_cast_helper::extract(static_cast(UINT8_C(0))) + ); + } + else + { + unsigned_integer_type x(u); + + auto out_first = out; + + while(x != static_cast(UINT8_C(0))) // NOLINT(altera-id-dependent-backward-branch) + { + const auto c = + static_cast + ( + x % static_cast(BaseRepresentation) + ); + + *out = + static_cast + ( + baselexical_cast_helper::extract(c) + ); + + x = + static_cast + ( + x / static_cast(BaseRepresentation) + ); + + if(x != static_cast(UINT8_C(0))) + { + ++out; + } + } + + std::reverse(out_first, out + static_cast(UINT8_C(1))); + } + + return out + static_cast(UINT8_C(1)); + } + + #endif + + } // namespace util + +#endif // UTIL_BASELEXICAL_CAST_2020_06_28_H diff --git a/examples/chapter11_07/src/util/utility/util_bit_mask.h b/examples/chapter11_07/src/util/utility/util_bit_mask.h index 27f117e8c..446bf4a8e 100644 --- a/examples/chapter11_07/src/util/utility/util_bit_mask.h +++ b/examples/chapter11_07/src/util/utility/util_bit_mask.h @@ -1,80 +1,100 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_BIT_MASK_2010_06_13_H_ - #define UTIL_BIT_MASK_2010_06_13_H_ +#ifndef UTIL_BIT_MASK_2010_06_13_H + #define UTIL_BIT_MASK_2010_06_13_H #include namespace util { template + const unsigned BitPos, + const unsigned BitCnt> struct bit_mask_multi_value { + private: // This bit mask contains bit_cnt continuous bits starting at bit_pos. + static constexpr unsigned bit_pos = BitPos; + static constexpr unsigned bit_cnt = BitCnt; + // Ensure that the data_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the data_type of the bit_mask template must be an integer type"); // Ensure that the data_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the data_type of the bit_mask template must be unsigned"); // Ensure that the requested bit mask is in range. - static_assert((bit_pos + bit_cnt) <= unsigned(std::numeric_limits::digits), + static_assert((bit_pos + bit_cnt) <= unsigned { std::numeric_limits::digits }, "the requested bit_mask value exceeds the maximum value of the data_type"); - static const data_type value = static_cast(static_cast(static_cast(~static_cast(0U)) >> (std::numeric_limits::digits - (bit_cnt + 1U))) << bit_pos); + public: + static constexpr data_type value = + static_cast + ( + static_cast + ( + static_cast(~static_cast(0U)) >> static_cast(static_cast(std::numeric_limits::digits) - (bit_cnt + 1U)) + ) << bit_pos + ); }; template - struct bit_mask_multi_value + const unsigned BitPos> + struct bit_mask_multi_value { + private: // This bit mask contains one bit at bit_pos. + static constexpr unsigned bit_pos = BitPos; + // Ensure that the data_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the data_type of the bit_mask template must be an integer type"); // Ensure that the data_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the data_type of the bit_mask template must be unsigned"); // Ensure that the requested bit mask is in range. static_assert((bit_pos + 1) <= unsigned(std::numeric_limits::digits), "the requested bit_mask value exceeds the maximum value of the data_type"); - static const data_type value = static_cast(static_cast(1U) << bit_pos); + public: + static constexpr data_type value = static_cast(static_cast(1U) << bit_pos); }; template + const unsigned BitPos> struct bit_mask_single_value { + private: // This bit mask contains one bit at bit_pos. + static constexpr unsigned bit_pos = BitPos; + // Ensure that the data_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the data_type of the bit_mask template must be an integer type"); // Ensure that the data_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the data_type of the bit_mask template must be unsigned"); // Ensure that the requested bit mask is in range. static_assert((bit_pos + 1) <= unsigned(std::numeric_limits::digits), "the requested bit_mask value exceeds the maximum value of the data_type"); + public: static const data_type value = static_cast(static_cast(1U) << bit_pos); }; } -#endif // UTIL_BIT_MASK_2010_06_13_H_ +#endif // UTIL_BIT_MASK_2010_06_13_H diff --git a/examples/chapter11_07/src/util/utility/util_circular_buffer.h b/examples/chapter11_07/src/util/utility/util_circular_buffer.h deleted file mode 100644 index 39e8c67c5..000000000 --- a/examples/chapter11_07/src/util/utility/util_circular_buffer.h +++ /dev/null @@ -1,374 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2015. -// 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) -// - -#ifndef UTIL_CIRCULAR_BUFFER_2007_11_22_H_ - #define UTIL_CIRCULAR_BUFFER_2007_11_22_H_ - - #include - #include - #include - - namespace util - { - // Forward declaration of the circular_buffer class. - template - class circular_buffer; - - namespace circular_buffer_detail - { - template - struct circular_iterator : public std::iterator - { - public: - typedef std::iterator iterator_type; - - typedef typename iterator_type::value_type value_type; - typedef typename iterator_type::pointer pointer; - typedef typename iterator_type::reference reference; - typedef const reference const_reference; - typedef typename std::size_t size_type; - typedef typename iterator_type::difference_type difference_type; - - explicit circular_iterator(const pointer pb, - const pointer pc = pb) : buffer_pointer (pb), - circular_pointer(pc) { } - - ~circular_iterator() { } - - circular_iterator& operator=(const circular_iterator& other_iterator) - { - if(this != &other_iterator) - { - buffer_pointer = other_iterator.buffer_pointer; - circular_pointer = other_iterator.circular_pointer; - } - - return *this; - } - - const_reference operator*() const - { - return *circular_pointer; - } - - reference operator*() - { - return *const_cast(circular_pointer); - } - - circular_iterator& operator++() - { - ++circular_pointer; - - if(circular_pointer > (buffer_pointer + difference_type(N))) - { - circular_pointer = buffer_pointer; - } - - return *this; - } - - circular_iterator& operator--() - { - --circular_pointer; - - if(circular_pointer < buffer_pointer) - { - circular_pointer = buffer_pointer + difference_type(N); - } - - return *this; - } - - circular_iterator operator++(int) - { - circular_iterator tmp = *this; - - ++(*this); - - return tmp; - } - - circular_iterator operator--(int) - { - circular_iterator tmp = *this; - - --(*this); - - return tmp; - } - - circular_iterator& operator+=(difference_type n) - { - if(n > difference_type(0)) - { - circular_pointer += n; - - if(circular_pointer > (buffer_pointer + difference_type(N))) - { - circular_pointer -= difference_type(N); - } - } - else if(n < 0) - { - *this -= -n; - } - - return *this; - } - - circular_iterator& operator-=(difference_type n) - { - if(n > difference_type(0)) - { - circular_pointer -= n; - - if(circular_pointer < buffer_pointer) - { - circular_pointer += difference_type(N); - } - } - else if(n < 0) - { - *this += -n; - } - - return *this; - } - - private: - pointer buffer_pointer; - pointer circular_pointer; - - circular_iterator(); - - friend inline circular_iterator operator+(const circular_iterator& a, difference_type n) { return circular_iterator(a) += n; } - friend inline circular_iterator operator-(const circular_iterator& a, difference_type n) { return circular_iterator(a) -= n; } - - friend inline bool operator==(const circular_iterator& a, const circular_iterator& b) { return (a.circular_pointer == b.circular_pointer); } - friend inline bool operator!=(const circular_iterator& a, const circular_iterator& b) { return (a.circular_pointer != b.circular_pointer); } - - // TBD: Implement operator<(). - // TBD: Implement the remaining operators. - }; - } - - template - class circular_buffer - { - public: - static_assert(N > std::size_t(0U), - "Error: The circular_buffer class requires more than zero elements."); - - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef value_type& reference; - typedef const value_type& const_reference; - - typedef circular_buffer_detail::circular_iterator > iterator; - typedef circular_buffer_detail::circular_iterator > const_iterator; - - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - circular_buffer() : buffer (), - my_size(difference_type(0)), - first (buffer + difference_type(N)), - last (buffer + difference_type(N)) - { - std::fill(buffer, buffer + difference_type(N), value_type()); - } - - explicit circular_buffer(const size_type count, - const value_type value = value_type()) : buffer (), - my_size(difference_type(count)), - first (buffer + difference_type(N - count)), - last (buffer + difference_type(N)) - { - std::fill(buffer, buffer + difference_type(N - count), value_type()); - - std::fill(buffer + difference_type(N - count), buffer + difference_type(N), value); - } - - circular_buffer(const circular_buffer& other) : buffer (), - my_size(difference_type(other.size())), - first (buffer + difference_type(other.first - other.buffer)), - last (buffer + difference_type(other.last - other.buffer)) - { - std::copy(other.buffer, other.buffer + difference_type(N), buffer); - } - - ~circular_buffer() { } - - circular_buffer& operator=(const circular_buffer& other) - { - if(this != &other) - { - std::copy(other.buffer, other.buffer + difference_type(N), buffer); - - my_size = difference_type(other.size()); - - first = buffer + difference_type(other.first - other.buffer); - last = buffer + difference_type(other.last - other.buffer); - } - - return *this; - } - - static size_type capacity() { return N; } - - bool empty() const - { - return (my_size == difference_type(0U)); - } - - size_type size() const - { - return size_type(my_size); - } - - void clear() - { - first = buffer; - last = buffer + difference_type(N); - my_size = difference_type(0); - } - - void push_front(const value_type value) - { - --first; - - if(first < buffer) - { - first = buffer + difference_type(N - 1U); - } - - *first = value; - - if(my_size < difference_type(N)) - { - ++my_size; - } - } - - void pop_back() - { - if(my_size > difference_type(0)) - { - --my_size; - - // TBD: Do we actually need to manually call the destructor here? - last->~value_type(); - - --last; - - if(last <= buffer) - { - last = buffer + difference_type(N); - } - } - } - - iterator begin () { return iterator (buffer, first); } - const_iterator begin () const { return const_iterator(buffer, first); } - const_iterator cbegin() const { return const_iterator(buffer, first); } - iterator end () { return iterator (buffer, last); } - const_iterator end () const { return const_iterator(buffer, last); } - const_iterator cend () const { return const_iterator(buffer, last); } - - reverse_iterator rbegin () { return std::reverse_iterator (iterator (buffer, last)); } - const_reverse_iterator rbegin () const { return std::reverse_iterator(const_iterator(buffer, last)); } - const_reverse_iterator crbegin() const { return std::reverse_iterator(const_iterator(buffer, last)); } - reverse_iterator rend () { return std::reverse_iterator (iterator (buffer, first)); } - const_reverse_iterator rend () const { return std::reverse_iterator(const_iterator(buffer, first)); } - const_reverse_iterator crend () const { return std::reverse_iterator(const_iterator(buffer, first)); } - - reference front () { return *begin(); } - const_reference front () const { return *begin(); } - reference back () { return *(end() - iterator::difference_type(1)); } - const_reference back () const { return *(cend() - const_iterator::difference_type(1)); } - - private: - value_type buffer[N]; - difference_type my_size; - pointer first; - pointer last; - }; - } - - /* - #include - #include - #include - #include - - template - void do_something() - { - circular_buffer_type cb(1U, 1U); - - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - cb.push_front(2U); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - cb.push_front(3U); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - cb.pop_back(); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - cb.pop_back(); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - cb.pop_back(); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - cb.push_front(101U); - cb.push_front(102U); - cb.push_front(103U); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - for(auto it = cb.cbegin(); it != cb.cbegin() + cb.size(); ++it) { std::cout << *it << std::endl; } - for(auto it = cb.crbegin(); it != cb.crend(); ++it) { std::cout << *it << std::endl; } - - cb.pop_back(); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - cb.pop_back(); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - cb.push_front(42U); - std::cout << cb.size() << ", " << cb.front() << ", " << cb.back() << std::endl; - - circular_buffer_type other_cb; - - other_cb = cb; - - volatile unsigned debug = 0U; - - static_cast(debug); - } - - int main() - { - do_something>(); - } -*/ - -#endif // UTIL_CIRCULAR_BUFFER_2007_11_22_H_ diff --git a/examples/chapter11_07/src/util/utility/util_communication.h b/examples/chapter11_07/src/util/utility/util_communication.h index 9e61a65e1..e8981ff55 100644 --- a/examples/chapter11_07/src/util/utility/util_communication.h +++ b/examples/chapter11_07/src/util/utility/util_communication.h @@ -1,76 +1,73 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +// Copyright Christopher Kormanyos 2007 - 2022. // 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) // -#ifndef UTIL_COMMUNICATION_2012_05_31_H_ - #define UTIL_COMMUNICATION_2012_05_31_H_ +#ifndef UTIL_COMMUNICATION_2012_05_31_H + #define UTIL_COMMUNICATION_2012_05_31_H + + #include #include + #include #include #include - #include - namespace util { - class communication_base : private util::noncopyable + class communication_base : private util::noncopyable // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: virtual ~communication_base() = default; - virtual bool recv(std::uint8_t& byte_to_recv) = 0; + virtual auto recv(std::uint8_t& byte_to_recv) -> bool = 0; - virtual void select() = 0; - virtual void deselect() = 0; + virtual auto select() -> void = 0; + virtual auto deselect() -> void = 0; - virtual bool select_channel(const std::size_t) { return true; } + virtual auto select_channel(const std::size_t) -> bool { return true; } template - bool send_n(send_iterator_type first, send_iterator_type last) + auto send_n(send_iterator_type first, send_iterator_type last) noexcept -> bool { - using send_value_type = typename std::iterator_traits::value_type; - - bool send_result = true; + bool send_result { true }; // NOLINT(altera-id-dependent-backward-branch) - while(first != last) + while((first != last) && send_result) // NOLINT(altera-id-dependent-backward-branch) { - const send_value_type value(*first); - - send_result &= this->send(std::uint8_t(value)); + using send_value_type = typename std::iterator_traits::value_type; - ++first; + send_result = (this->send(static_cast(send_value_type(*first++))) && send_result); } return send_result; } + virtual auto send(const std::uint8_t byte_to_send) noexcept -> bool = 0; + protected: communication_base() = default; private: - virtual bool send(const std::uint8_t byte_to_send) = 0; - - template + template friend class communication_multi_channel; }; - class communication_buffer_depth_one_byte : public communication_base + class communication_buffer_depth_one_byte : public communication_base // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: - typedef std::uint8_t buffer_type; + using buffer_type = std::uint8_t; - virtual ~communication_buffer_depth_one_byte() = default; + ~communication_buffer_depth_one_byte() override = default; protected: - communication_buffer_depth_one_byte() : recv_buffer(0U) { } + buffer_type recv_buffer { }; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes) - buffer_type recv_buffer; + communication_buffer_depth_one_byte() = default; private: - virtual bool recv(std::uint8_t& byte_to_recv) + auto recv(std::uint8_t& byte_to_recv) -> bool override { byte_to_recv = recv_buffer; @@ -78,45 +75,36 @@ } }; - template - class communication_multi_channel : public communication_base + template + class communication_multi_channel : public communication_base // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { private: - static_assert(channel_count > 0U, "Error channel_count must be greater than zero."); + static constexpr std::size_t channel_count = ChannelCount; public: - communication_multi_channel(communication_base** p_com_channels) - : my_com_channels(), - my_index (0U) + communication_multi_channel() = delete; + + explicit communication_multi_channel(communication_base** p_com_channels) { - for(std::size_t i = 0U; i < channel_count; ++i) - { - my_com_channels[i] = p_com_channels[i]; - } + std::copy(p_com_channels, p_com_channels + channel_count, my_com_channels.begin()); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) } - ~communication_multi_channel() = default; - - private: - communication_base* my_com_channels[channel_count]; - std::size_t my_index; - - communication_multi_channel() = delete; + ~communication_multi_channel() override = default; - virtual bool send(const std::uint8_t byte_to_send) + auto send(const std::uint8_t byte_to_send) noexcept -> bool override { return my_com_channels[my_index]->send(byte_to_send); } - virtual bool recv(std::uint8_t& byte_to_recv) + auto recv(std::uint8_t& byte_to_recv) -> bool override { return my_com_channels[my_index]->recv(byte_to_recv); } - virtual void select() { my_com_channels[my_index]->select(); } - virtual void deselect() { my_com_channels[my_index]->deselect(); } + auto select() -> void override { my_com_channels[my_index]->select(); } + auto deselect() -> void override { my_com_channels[my_index]->deselect(); } - virtual bool select_channel(const std::size_t index) + auto select_channel(const std::size_t index) -> bool override { const bool select_channel_is_ok = (index < channel_count); @@ -127,7 +115,13 @@ return select_channel_is_ok; } + + private: + std::array my_com_channels { }; // NOLINT(readability-identifier-naming) + std::size_t my_index { }; // NOLINT(readability-identifier-naming) + + static_assert(channel_count > 0U, "Error channel_count must be greater than zero."); }; - } + } // namespace util -#endif // UTIL_COMMUNICATION_2012_05_31_H_ +#endif // UTIL_COMMUNICATION_2012_05_31_H diff --git a/examples/chapter11_07/src/util/utility/util_countof.h b/examples/chapter11_07/src/util/utility/util_countof.h index d3a144dd4..1524259e0 100644 --- a/examples/chapter11_07/src/util/utility/util_countof.h +++ b/examples/chapter11_07/src/util/utility/util_countof.h @@ -1,46 +1,26 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. +// Copyright Christopher Kormanyos 2014 - 2024. // 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) // -#ifndef UTIL_COUNTOF_2014_09_29_H_ - #define UTIL_COUNTOF_2014_09_29_H_ +#ifndef UTIL_COUNTOF_2014_09_29_H + #define UTIL_COUNTOF_2014_09_29_H #include namespace util { - #if defined(__GNUC__) + template + inline constexpr auto countof(T(&c_array)[N]) -> std::size_t + { + static_assert(N > std::size_t(0U), "Error: util::countof requires an array size larger than zero."); - template - inline constexpr std::size_t countof(T(&c_array)[N]) - { - static_assert(N > std::size_t(0U), - "Sorry, util::countof requires an array size larger than zero."); + static_assert(sizeof(c_array[0U]) > std::size_t(0U), "Error: util::countof requires an element size larger than zero."); - static_assert(sizeof(c_array[0U]) > std::size_t(0U), - "Sorry, util::countof requires an element size larger than zero."); - - return sizeof(c_array) / sizeof(c_array[0U]); - } - - #else - - template - inline std::size_t countof(T(&c_array)[N]) - { - static_assert(N > std::size_t(0U), - "Sorry, util::countof requires an array size larger than zero."); - - static_assert(sizeof(c_array[0U]) > std::size_t(0U), - "Sorry, util::countof requires an element size larger than zero."); - - return sizeof(c_array) / sizeof(c_array[0U]); - } - - #endif + return sizeof(c_array) / sizeof(c_array[0U]); + } } -#endif // UTIL_COUNTOF_2014_09_29_H_ +#endif // UTIL_COUNTOF_2014_09_29_H diff --git a/examples/chapter11_07/src/util/utility/util_display.h b/examples/chapter11_07/src/util/utility/util_display.h new file mode 100644 index 000000000..b3176185f --- /dev/null +++ b/examples/chapter11_07/src/util/utility/util_display.h @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2019 - 2024. +// 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) +// + +#ifndef UTIL_DISPLAY_2023_06_09_H + #define UTIL_DISPLAY_2023_06_09_H + + #include + #include + + #include + + namespace util { + + class display_multiline_base : private util::noncopyable + { + public: + virtual ~display_multiline_base() = default; + + virtual auto init() -> bool = 0; + + virtual auto write(const char* pstr, + const std::uint_fast8_t length, + const std::uint_fast8_t line_index) -> bool = 0; + + virtual auto clear_line(const unsigned = static_cast(UINT8_C(0))) -> bool = 0; + + virtual auto set_line_index(const std::uint8_t) -> bool = 0; + + protected: + display_multiline_base() = default; + + using timer_type = util::timer; + + static auto blocking_delay(const typename timer_type::tick_type blocking_delay_value) -> void + { + timer_type::blocking_delay(blocking_delay_value); + } + }; + + } // namespace util + +#endif // UTIL_DISPLAY_2023_06_09_H diff --git a/examples/chapter11_07/src/util/utility/util_dynamic_array.h b/examples/chapter11_07/src/util/utility/util_dynamic_array.h index 3165f0934..9c9f18b97 100644 --- a/examples/chapter11_07/src/util/utility/util_dynamic_array.h +++ b/examples/chapter11_07/src/util/utility/util_dynamic_array.h @@ -1,294 +1,311 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2012 - 2024. // 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) // -#ifndef UTIL_DYNAMIC_ARRAY_2012_05_16_H_ - #define UTIL_DYNAMIC_ARRAY_2012_05_16_H_ +#ifndef UTIL_DYNAMIC_ARRAY_2012_05_16_H // NOLINT(llvm-header-guard) + #define UTIL_DYNAMIC_ARRAY_2012_05_16_H #include + #include + #include #include #include #include #include - namespace util + namespace util { + + template, + typename SizeType = std::size_t, + typename DiffType = std::ptrdiff_t> + class dynamic_array; + + template + class dynamic_array { - template> - class dynamic_array + public: + // Type definitions. + using allocator_type = typename std::allocator_traits::template rebind_alloc; + using value_type = typename allocator_type::value_type; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = value_type*; + using const_iterator = const value_type*; + using pointer = value_type*; + using const_pointer = const value_type*; + using size_type = SizeType; + using difference_type = DiffType; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // Constructors. + explicit constexpr dynamic_array( size_type count = static_cast(UINT8_C(0)), + const_reference v = value_type(), + const allocator_type& a = allocator_type()) + : elem_count(count) { - public: - // Type definitions. - typedef alloc allocator_type; - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* iterator; - typedef const T* const_iterator; - typedef T* pointer; - typedef const T* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - // Constructors. - dynamic_array() : elem_count(0U), - elems (nullptr) { } - - dynamic_array(size_type count) : elem_count(count), - elems (elem_count > 0U ? allocator_type().allocate(elem_count) : nullptr) + if(elem_count > static_cast(UINT8_C(0))) { - for(auto it_self = begin(); it_self != end(); ++it_self) - { - allocator_type().construct(it_self, value_type()); - } - } + allocator_type my_a(a); - dynamic_array(size_type count, - const value_type& v, - const allocator_type& a = allocator_type()) - : elem_count(count), - elems (elem_count > 0U ? allocator_type(a).allocate(elem_count) : nullptr) - { - for(auto it_self = begin(); it_self != end(); ++it_self) - { - allocator_type(a).construct(it_self, v); - } - } + elems = std::allocator_traits::allocate(my_a, elem_count); - dynamic_array(const dynamic_array& other) - : elem_count(other.size()), - elems (elem_count > 0U ? allocator_type().allocate(elem_count) : nullptr) - { - auto it_other = other.cbegin(); + iterator it = begin(); - for(auto it_self = begin(); it_self != end(); ++it_self) + while(it != end()) { - allocator_type().construct(it_self, *it_other++); + std::allocator_traits::construct(my_a, it, v); + + ++it; } } + } - template - dynamic_array(input_iterator first, - input_iterator last, - const allocator_type& a = allocator_type()) - : elem_count(static_cast(std::distance(first, last))), - elems (elem_count > 0U ? allocator_type(a).allocate(elem_count) : nullptr) + constexpr dynamic_array(const dynamic_array& other) + : elem_count(other.size()) + { + allocator_type my_a; + + if(elem_count > static_cast(UINT8_C(0))) { - for(auto it_self = begin(); it_self != end(); ++it_self) - { - allocator_type(a).construct(it_self, *first++); - } + elems = std::allocator_traits::allocate(my_a, elem_count); } - dynamic_array(std::initializer_list lst, - const allocator_type& a = allocator_type()) - : elem_count(lst.size()), - elems (elem_count > 0U ? allocator_type(a).allocate(elem_count) : nullptr) - { - auto it_lst = lst.begin(); + std::copy(other.elems, other.elems + elem_count, elems); + } - for(auto it_self = begin(); it_self != end(); ++it_self) - { - allocator_type(a).construct(it_self, *it_lst++); - } - } + template + constexpr dynamic_array(input_iterator first, + input_iterator last, + const allocator_type& a = allocator_type()) + : elem_count(static_cast(std::distance(first, last))) + { + allocator_type my_a(a); - // Move constructor. - dynamic_array(dynamic_array&& other) : elem_count(other.elem_count), - elems (other.elems) + if(elem_count > static_cast(UINT8_C(0))) { - other.elem_count = 0U; - other.elems = nullptr; + elems = std::allocator_traits::allocate(my_a, elem_count); } - // Destructor. - virtual ~dynamic_array() - { - // Destroy the elements and deallocate the range. - if(elem_count > size_type(0U)) - { - for(pointer p = elems; p != (elems + elem_count); ++p) - { - allocator_type().destroy(p); - } + std::copy(first, last, elems); + } - allocator_type().deallocate(elems, elem_count); - } - } + constexpr dynamic_array(std::initializer_list lst, + const allocator_type& a = allocator_type()) + : elem_count(lst.size()) + { + allocator_type my_a(a); - // Assignment operator. - dynamic_array& operator=(const dynamic_array& other) + if(elem_count > static_cast(UINT8_C(0))) { - if(this != &other) - { - std::copy(other.elems, - other.elems + (std::min)(elem_count, other.elem_count), - elems); - } - - return *this; + elems = std::allocator_traits::allocate(my_a, elem_count); } - // Move assignment operator. - dynamic_array& operator=(dynamic_array&& other) - { - // Destroy the elements and deallocate the range. - if(elem_count > size_type(0U)) - { - for(pointer p = elems; p != (elems + elem_count); ++p) - { - allocator_type().destroy(p); - } + std::copy(lst.begin(), lst.end(), elems); + } - allocator_type().deallocate(elems, elem_count); - } + // Move constructor. + constexpr dynamic_array(dynamic_array&& other) noexcept : elem_count(other.elem_count), + elems (other.elems) + { + other.elem_count = static_cast(UINT8_C(0)); + other.elems = nullptr; + } - elem_count = other.elem_count; - elems = other.elems; + // Destructor. + virtual ~dynamic_array() // LCOV_EXCL_LINE + { + using local_allocator_traits_type = std::allocator_traits; - other.elem_count = 0U; - other.elems = nullptr; + allocator_type my_a; - return *this; - } + // Destroy the elements and deallocate the range. + local_allocator_traits_type::deallocate(my_a, elems, elem_count); + } - // Iterator members: - iterator begin () { return elems; } - iterator end () { return elems + elem_count; } - const_iterator begin () const { return elems; } - const_iterator end () const { return elems + elem_count; } - const_iterator cbegin () const { return elems; } - const_iterator cend () const { return elems + elem_count; } - reverse_iterator rbegin () { return reverse_iterator(elems + elem_count); } - reverse_iterator rend () { return reverse_iterator(elems); } - const_reverse_iterator rbegin () const { return const_reverse_iterator(elems + elem_count); } - const_reverse_iterator rend () const { return const_reverse_iterator(elems); } - const_reverse_iterator crbegin() const { return const_reverse_iterator(elems + elem_count); } - const_reverse_iterator crend () const { return const_reverse_iterator(elems); } - - // Raw pointer access. - pointer data() noexcept + // Assignment operator. + constexpr auto operator=(const dynamic_array& other) -> dynamic_array& + { + if(this != &other) { - return elems; + std::copy(other.elems, + other.elems + (std::min)(elem_count, other.elem_count), + elems); } - // Size and capacity. - size_type size () const { return elem_count; } - size_type max_size() const { return elem_count; } - bool empty () const { return (elem_count == 0U); } - - // Element access members. - reference operator[](const size_type i) { return elems[i]; } - const_reference operator[](const size_type i) const { return elems[i]; } - - reference front() { return elems[0U]; } - const_reference front() const { return elems[0U]; } + return *this; + } - reference back() { return ((elem_count > size_type(0U)) ? elems[elem_count - 1U] : elems[0U]); } - const_reference back() const { return ((elem_count > size_type(0U)) ? elems[elem_count - 1U] : elems[0U]); } + // Move assignment operator. + constexpr auto operator=(dynamic_array&& other) noexcept -> dynamic_array& + { + std::swap(elem_count, other.elem_count); + std::swap(elems, other.elems); - reference at(const size_type i) { return ((i < elem_count) ? elems[i] : elems[0U]); } - const_reference at(const size_type i) const { return ((i < elem_count) ? elems[i] : elems[0U]); } + return *this; + } - // Element manipulation members. - void fill(const value_type& v) { std::fill_n(begin(), elem_count, v); } + // Iterator members: + constexpr auto begin () noexcept -> iterator { return elems; } + constexpr auto end () noexcept -> iterator { return elems + elem_count; } + constexpr auto begin () const noexcept -> const_iterator { return elems; } + constexpr auto end () const noexcept -> const_iterator { return elems + elem_count; } + constexpr auto cbegin () const noexcept -> const_iterator { return elems; } + constexpr auto cend () const noexcept -> const_iterator { return elems + elem_count; } + constexpr auto rbegin () noexcept -> reverse_iterator { return reverse_iterator(elems + elem_count); } + constexpr auto rend () noexcept -> reverse_iterator { return reverse_iterator(elems); } + constexpr auto rbegin () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + constexpr auto rend () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems); } + constexpr auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + constexpr auto crend () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems); } + + // Raw pointer access. + constexpr auto data() noexcept -> pointer { return elems; } + constexpr auto data() const noexcept -> const_pointer { return elems; } + + // Size and capacity. + constexpr auto size () const noexcept -> size_type { return elem_count; } + constexpr auto max_size() const noexcept -> size_type { return elem_count; } + constexpr auto empty () const noexcept -> bool { return (elem_count == static_cast(UINT8_C(0))); } + + // Element access members. + constexpr auto operator[](const size_type i) noexcept -> reference { return elems[i]; } + constexpr auto operator[](const size_type i) const noexcept -> const_reference { return elems[i]; } + + constexpr auto front() noexcept -> reference { return elems[static_cast(UINT8_C(0))]; } + constexpr auto front() const noexcept -> const_reference { return elems[static_cast(UINT8_C(0))]; } + + constexpr auto back() noexcept -> reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } + constexpr auto back() const noexcept -> const_reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } + + constexpr auto at(const size_type i) noexcept -> reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + constexpr auto at(const size_type i) const noexcept -> const_reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + + // Element manipulation members. + constexpr auto fill(const value_type& v) -> void + { + std::fill(begin(), begin() + elem_count, v); + } - void swap(dynamic_array& other) + constexpr auto swap(dynamic_array& other) noexcept -> void + { + if(this != &other) { - const size_type tmp_elem_count = elem_count; - const pointer tmp_elems = elems; + std::swap(elems, other.elems); + std::swap(elem_count, other.elem_count); + } + } - elem_count = other.elem_count; - elems = other.elems; + constexpr auto swap(dynamic_array&& other) noexcept -> void + { + elems = std::move(other.elems); + elem_count = std::move(other.elem_count); + } - other.elem_count = tmp_elem_count; - other.elems = tmp_elems; - } + private: + size_type elem_count; // NOLINT(readability-identifier-naming) + pointer elems { nullptr }; // NOLINT(readability-identifier-naming,altera-id-dependent-backward-branch) + }; - private: - mutable size_type elem_count; - pointer elems; - }; + template + auto operator==(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + bool left_and_right_are_equal = false; - template - bool operator==(const dynamic_array& lhs, const dynamic_array& rhs) + if(lhs.size() == rhs.size()) { - const bool sizes_are_equal = (lhs.size() == rhs.size()); + using size_type = typename dynamic_array::size_type; - typedef typename dynamic_array::size_type size_type; + const auto size_of_left_is_zero = (lhs.size() == static_cast(UINT8_C(0))); - const bool size_of_left_is_zero = (lhs.size() == size_type(0U)); - - return (sizes_are_equal && (size_of_left_is_zero || std::equal(lhs.begin(), lhs.end(), rhs.begin()))); + left_and_right_are_equal = + (size_of_left_is_zero || std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin())); } - template - bool operator<(const dynamic_array& lhs, const dynamic_array& rhs) - { - typedef typename dynamic_array::size_type size_type; + return left_and_right_are_equal; + } - const bool size_of_left_is_zero = (lhs.size() == size_type(0U)); + template + auto operator<(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + using size_type = typename dynamic_array::size_type; + + const auto size_of_left_is_zero = (lhs.size() == static_cast(UINT8_C(0))); + + bool b_result { }; + if(size_of_left_is_zero) + { + const auto size_of_right_is_zero = (rhs.size() == static_cast(UINT8_C(0))); + + b_result = (!size_of_right_is_zero); + } + else + { if(size_of_left_is_zero) { - const bool size_of_right_is_zero = (rhs.size() == size_type(0U)); + const auto size_of_right_is_zero = (rhs.size() == static_cast(UINT8_C(0))); - return (size_of_right_is_zero ? false : true); + b_result = (!size_of_right_is_zero); } else { - if(size_of_left_is_zero) - { - const bool size_of_right_is_zero = (rhs.size() == size_type(0U)); - - return (size_of_right_is_zero == false); - } - else - { - const size_type count = (std::min)(lhs.size(), rhs.size()); + const size_type count = (std::min)(lhs.size(), rhs.size()); - return std::lexicographical_compare(lhs.begin(), - lhs.begin() + count, - rhs.begin(), - rhs.begin() + count); - } + b_result= std::lexicographical_compare(lhs.cbegin(), + lhs.cbegin() + count, + rhs.cbegin(), + rhs.cbegin() + count); } } - template - bool operator!=(const dynamic_array& lhs, const dynamic_array& rhs) - { - return ((lhs == rhs) == false); - } + return b_result; + } - template - bool operator>(const dynamic_array& lhs, const dynamic_array& rhs) - { - return (rhs < lhs); - } + template + auto operator!=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + return (!(lhs == rhs)); + } - template - bool operator>=(const dynamic_array& lhs, const dynamic_array& rhs) - { - return ((lhs < rhs) == false); - } + template + auto operator>(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + return (rhs < lhs); + } - template - bool operator<=(const dynamic_array& lhs, const dynamic_array& rhs) - { - return ((rhs < lhs) == false); - } + template + auto operator>=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + return (!(lhs < rhs)); + } - template - void swap(dynamic_array& x, dynamic_array& y) - { - x.swap(y); - } + template + auto operator<=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool + { + return (!(rhs < lhs)); } -#endif // UTIL_DYNAMIC_ARRAY_2012_05_16_H_ + template + auto swap(dynamic_array& x, + dynamic_array& y) noexcept -> void + { + x.swap(y); + } + + } // namespace util + +#endif // UTIL_DYNAMIC_ARRAY_2012_05_16_H diff --git a/examples/chapter11_07/src/util/utility/util_dynamic_bitset.h b/examples/chapter11_07/src/util/utility/util_dynamic_bitset.h index df9ca913e..684aebaea 100644 --- a/examples/chapter11_07/src/util/utility/util_dynamic_bitset.h +++ b/examples/chapter11_07/src/util/utility/util_dynamic_bitset.h @@ -2,103 +2,56 @@ #define UTIL_DYNAMIC_BITSET_2018_02_03_H_ #include - #include #include #include namespace util { - template + template> class dynamic_bitset { - private: - static_assert(bit_count > 0U, - "error: the bit_count in dynamic_bitset must exceed zero."); - public: - using size_type = std::size_t; - using value_type = T; using allocator_type = alloc; - static constexpr std::size_t elem_digits = - static_cast(std::numeric_limits::digits); + static const std::size_t my_elem_count = (my_bit_count / 8U) + (((my_bit_count % 8U) != 0U) ? 1U : 0U); - static constexpr size_type elem_count = - size_type(bit_count / elem_digits) - + ((size_type(bit_count % elem_digits) != 0U) ? 1U : 0U); - - dynamic_bitset() : my_memory(allocator_type().allocate(elem_count)) + dynamic_bitset() : my_memory(allocator_type().allocate(my_elem_count)) { std::fill(my_memory, - my_memory + elem_count, - value_type(0U)); + my_memory + my_elem_count, + UINT8_C(0)); } ~dynamic_bitset() { - allocator_type().deallocate(my_memory, elem_count); + std::allocator_traits::deallocate(allocator_type(), my_memory, my_elem_count); } void set(const std::size_t i) { - my_memory[i / elem_digits] |= value_type(value_type(1ULL) << (i % elem_digits)); - } - - void set() - { - for(std::uint_fast8_t i = 0U; (i < std::uint_fast8_t(bit_count % elem_digits)); ++i) - { - my_memory[elem_count - 1U] |= value_type(value_type(1ULL) << i); - } - - for(std::uint_fast8_t i = 0U; (i < (elem_count - 1U)); ++i) - { - my_memory[i] |= (std::numeric_limits::max)(); - } + my_memory[i / 8U] |= (UINT8_C(1) << (i % 8U)); } void flip(const std::size_t i) { - my_memory[i / elem_digits] ^= (UINT8_C(1) << (i % elem_digits)); + my_memory[i / 8U] ^= (UINT8_C(1) << (i % 8U)); } bool test(const std::size_t i) const { - const value_type test_value = - (my_memory[i / elem_digits] & value_type(value_type(1ULL) << (i % elem_digits))); + const std::uint8_t test_value = (my_memory[i / 8U] & (UINT8_C(1) << (i % 8U))); return (test_value != 0U); } - bool any() const - { - return std::any_of(my_memory, - my_memory + elem_count, - [](const value_type& value) -> bool - { - return (value != 0U); - }); - } - - bool none() const - { - return std::all_of(my_memory, - my_memory + elem_count, - [](const value_type& value) -> bool - { - return (value == 0U); - }); - } - - static constexpr size_type size() + static std::size_t size() { - return bit_count; + return my_bit_count; } private: - typename allocator_type::pointer my_memory; + std::uint8_t* my_memory; }; } // namespace util diff --git a/examples/chapter11_07/src/util/utility/util_linear_interpolate.h b/examples/chapter11_07/src/util/utility/util_linear_interpolate.h index 93061476b..f154433a5 100644 --- a/examples/chapter11_07/src/util/utility/util_linear_interpolate.h +++ b/examples/chapter11_07/src/util/utility/util_linear_interpolate.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_LINEAR_INTERPOLATE_2008_11_22_H_ - #define UTIL_LINEAR_INTERPOLATE_2008_11_22_H_ +#ifndef UTIL_LINEAR_INTERPOLATE_2008_11_22_H + #define UTIL_LINEAR_INTERPOLATE_2008_11_22_H #include @@ -15,18 +15,17 @@ template - y_type linear_interpolate(point_iterator pts_begin, - point_iterator pts_end, - const x_type& x, - const y_type& offset) + auto linear_interpolate(point_iterator pts_begin, + point_iterator pts_end, + const x_type& x, + const y_type& offset) -> y_type { if(pts_begin == pts_end) { // There are no data points to interpolate. return y_type(); } - else if( (x <= pts_begin->x) - || ((pts_begin + 1U) == pts_end)) + else if((x <= pts_begin->x) || ((pts_begin + 1U) == pts_end)) { // We are beneath the lower x-range or there // is only one data point to interpolate. @@ -58,4 +57,4 @@ } } -#endif // UTIL_LINEAR_INTERPOLATE_2008_11_22_H_ +#endif // UTIL_LINEAR_INTERPOLATE_2008_11_22_H diff --git a/examples/chapter11_07/src/util/utility/util_narrow_cast.h b/examples/chapter11_07/src/util/utility/util_narrow_cast.h new file mode 100644 index 000000000..6b4416a61 --- /dev/null +++ b/examples/chapter11_07/src/util/utility/util_narrow_cast.h @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2020. +// 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) +// + +#ifndef UTIL_NARROW_CAST_2020_09_24_H + #define UTIL_NARROW_CAST_2020_09_24_H + + #include + + namespace util + { + template + constexpr auto narrow_cast(U&& u) noexcept -> T + { + return static_cast(std::forward(u)); + } + } + +#endif // UTIL_NARROW_CAST_2020_09_24_H diff --git a/examples/chapter11_07/src/util/utility/util_noncopyable.h b/examples/chapter11_07/src/util/utility/util_noncopyable.h index 3dabbaa7e..8f45b4e99 100644 --- a/examples/chapter11_07/src/util/utility/util_noncopyable.h +++ b/examples/chapter11_07/src/util/utility/util_noncopyable.h @@ -1,33 +1,37 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2023. // 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) // -#ifndef UTIL_NONCOPYABLE_2008_12_16_H_ - #define UTIL_NONCOPYABLE_2008_12_16_H_ +#ifndef UTIL_NONCOPYABLE_2008_12_16_H // NOLINT(llvm-header-guard) + #define UTIL_NONCOPYABLE_2008_12_16_H // Taken (with slight modification) from boost::noncopyable. - namespace util + namespace util { + namespace my_noncopyable_namespace { + + class noncopyable { - namespace my_noncopyable_namespace - { - class noncopyable - { - protected: - noncopyable() = default; - ~noncopyable() = default; - - private: - // Emphasize: The following members are private. - noncopyable(const noncopyable&) = delete; - noncopyable& operator=(const noncopyable&) = delete; - }; - } - - using noncopyable = my_noncopyable_namespace::noncopyable; - } - -#endif // UTIL_NONCOPYABLE_2008_12_16_H_ + protected: + noncopyable() = default; // LCOV_EXCL_LINE + ~noncopyable() = default; // LCOV_EXCL_LINE + + private: + // Emphasize: The following members are private. + noncopyable(const noncopyable&) = delete; // NOLINT(hicpp-use-equals-delete,modernize-use-equals-delete) + noncopyable(noncopyable&&) = delete; // NOLINT(hicpp-use-equals-delete,modernize-use-equals-delete) + + auto operator=(const noncopyable&) -> noncopyable& = delete; // NOLINT(hicpp-use-equals-delete,modernize-use-equals-delete) + auto operator=(noncopyable&&) -> noncopyable& = delete; // NOLINT(hicpp-use-equals-delete,modernize-use-equals-delete) + }; + + } // namespace my_noncopyable_namespace + + using noncopyable = my_noncopyable_namespace::noncopyable; + + } // namespace util + +#endif // UTIL_NONCOPYABLE_2008_12_16_H diff --git a/examples/chapter11_07/src/util/utility/util_nothing.h b/examples/chapter11_07/src/util/utility/util_nothing.h index 692e46cbc..a5ff0c506 100644 --- a/examples/chapter11_07/src/util/utility/util_nothing.h +++ b/examples/chapter11_07/src/util/utility/util_nothing.h @@ -1,33 +1,35 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_NOTHING_2010_06_13_H_ - #define UTIL_NOTHING_2010_06_13_H_ +#ifndef UTIL_NOTHING_2010_06_13_H + #define UTIL_NOTHING_2010_06_13_H namespace util { // This is a structure that is used to represent *nothing*. struct nothing final { - nothing() = default; + constexpr nothing() = default; - nothing(const nothing&) { } + constexpr nothing(const nothing&) { } + constexpr nothing(nothing&&) noexcept { } ~nothing() = default; - nothing& operator=(const nothing&) { return *this; } + constexpr auto operator=(const nothing&) -> nothing& { return *this; } + constexpr auto operator=(nothing&&) noexcept -> nothing& { return *this; } }; - inline bool operator==(const nothing&, const nothing&) { return true; } - inline bool operator!=(const nothing&, const nothing&) { return false; } - inline bool operator< (const nothing&, const nothing&) { return false; } - inline bool operator<=(const nothing&, const nothing&) { return false; } - inline bool operator> (const nothing&, const nothing&) { return false; } - inline bool operator>=(const nothing&, const nothing&) { return false; } + inline constexpr auto operator==(const nothing&, const nothing&) noexcept -> bool { return true; } + inline constexpr auto operator!=(const nothing&, const nothing&) noexcept -> bool { return false; } + inline constexpr auto operator< (const nothing&, const nothing&) noexcept -> bool { return false; } + inline constexpr auto operator<=(const nothing&, const nothing&) noexcept -> bool { return false; } + inline constexpr auto operator> (const nothing&, const nothing&) noexcept -> bool { return false; } + inline constexpr auto operator>=(const nothing&, const nothing&) noexcept -> bool { return false; } } -#endif // UTIL_NOTHING_2010_06_13_H_ +#endif // UTIL_NOTHING_2010_06_13_H diff --git a/examples/chapter11_07/src/util/utility/util_point.h b/examples/chapter11_07/src/util/utility/util_point.h index 85cc2d65a..992fcecd0 100644 --- a/examples/chapter11_07/src/util/utility/util_point.h +++ b/examples/chapter11_07/src/util/utility/util_point.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2014. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_POINT_2008_11_22_H_ - #define UTIL_POINT_2008_11_22_H_ +#ifndef UTIL_POINT_2008_11_22_H + #define UTIL_POINT_2008_11_22_H namespace util { @@ -14,57 +14,62 @@ typename y_type = x_type> struct point { - x_type x; - y_type y; + x_type x { }; + y_type y { }; - point(const x_type& x0 = x_type(), - const y_type& y0 = y_type()) : x(x0), - y(y0) { } + explicit constexpr point(const x_type& x0 = x_type(), + const y_type& y0 = y_type()) : x { x0 }, + y { y0 } { } - point(const point& other) + constexpr point(const point& other) : x { other.x }, + y { other.y } { } + + constexpr point(point&& other) noexcept : x { other.x }, + y { other.y } { } + + ~point() = default; + + constexpr auto operator=(const point& other) -> point& { if(this != &other) { x = other.x; y = other.y; } - } - ~point() { } + return *this; + } - point& operator=(const point& other) + constexpr auto operator=(point&& other) noexcept -> point& { - if(this != &other) - { - x = other.x; - y = other.y; - } + x = other.x; + y = other.y; return *this; } - bool operator<(const point& other) const + constexpr auto operator<(const point& other) const -> bool { return (x < other.x); } }; template - bool operator==(const point& left, const point& right) + constexpr auto operator==(const point& left, const point& right) -> bool { return ( (left.x == right.x) && (left.y == right.y)); } template - bool operator!=(const point& left, const point& right) + constexpr auto operator!=(const point& left, const point& right) -> bool { return ( (left.x != right.x) || (left.y != right.y)); } template - bool operator<(const point& left, const point& right) + constexpr auto operator<(const point& left, const point& right) -> bool { return ((left.x < right.x) ? true @@ -74,22 +79,22 @@ } template - bool operator<=(const point& left, const point& right) + constexpr auto operator<=(const point& left, const point& right) -> bool { - return ((right < left) == false); + return (!(right < left)); } template - bool operator>(const point& left, const point& right) + constexpr auto operator>(const point& left, const point& right) -> bool { return (right < left); } template - bool operator>=(const point& left, const point& right) + constexpr auto operator>=(const point& left, const point& right) -> bool { - return ((left < right) == false); + return (!(left < right)); } - } + } // namespace util -#endif // UTIL_POINT_2008_11_22_H_ +#endif // UTIL_POINT_2008_11_22_H diff --git a/examples/chapter11_07/src/util/utility/util_random_pcg32.h b/examples/chapter11_07/src/util/utility/util_random_pcg32.h deleted file mode 100644 index 2ab6d36b2..000000000 --- a/examples/chapter11_07/src/util/utility/util_random_pcg32.h +++ /dev/null @@ -1,163 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2020. -// 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) -// - -#ifndef UTIL_RANDOM_PCG32_2020_01_17_H_ - #define UTIL_RANDOM_PCG32_2020_01_17_H_ - - #include - #include - #include - #include - - namespace util { - - class random_pcg32_fast_base - { - public: - // We use random 64-bit unsigned integer "strings" as part - // of the variable names within the wstp kernel. - // We use pcg32_fast for quick generation of pseudo-random numbers. - virtual ~random_pcg32_fast_base() = default; - - protected: - using internal_type = std::uint64_t; - - explicit random_pcg32_fast_base(const internal_type) { } - - random_pcg32_fast_base(const random_pcg32_fast_base&) = default; - - random_pcg32_fast_base& operator=(const random_pcg32_fast_base&) = default; - - template - static ArithmeticType rotr(const ArithmeticType& value_being_shifted, - const std::size_t bits_to_shift) - { - const std::size_t left_shift_amount = - std::numeric_limits::digits - bits_to_shift; - - const ArithmeticType part1 = ((bits_to_shift > 0U) ? ArithmeticType(value_being_shifted >> bits_to_shift) : value_being_shifted); - const ArithmeticType part2 = ((bits_to_shift > 0U) ? ArithmeticType(value_being_shifted << left_shift_amount) : 0U); - - return ArithmeticType(part1 | part2); - } - - template - static OutputType output(const InternalType internal_value) - { - using local_output_type = OutputType; - using local_internal_type = InternalType; - - using bitcount_t = std::size_t; - - constexpr bitcount_t bits = bitcount_t(sizeof(local_internal_type) * 8U); - constexpr bitcount_t xtypebits = bitcount_t(sizeof(local_output_type) * 8U); - constexpr bitcount_t sparebits = bits - xtypebits; - constexpr bitcount_t wantedopbits = ((xtypebits >= 128U) ? 7U - : ((xtypebits >= 64U) ? 6U - : ((xtypebits >= 32U) ? 5U - : ((xtypebits >= 16U) ? 4U - : 3U)))); - - constexpr bitcount_t opbits = ((sparebits >= wantedopbits) ? wantedopbits : sparebits); - constexpr bitcount_t amplifier = wantedopbits - opbits; - constexpr bitcount_t mask = (1ULL << opbits) - 1U; - constexpr bitcount_t topspare = opbits; - constexpr bitcount_t bottomspare = sparebits - topspare; - constexpr bitcount_t xshift = (topspare + xtypebits) / 2U; - - const bitcount_t rot = - ((opbits != 0U) ? (bitcount_t(internal_value >> (bits - opbits)) & mask) - : 0U); - - const bitcount_t amprot = (rot << amplifier) & mask; - - const local_internal_type internal_value_xor = internal_value ^ local_internal_type(internal_value >> xshift); - - const local_output_type result = random_pcg32_fast_base::rotr(local_output_type(internal_value_xor >> bottomspare), amprot); - - return result; - } - }; - - class random_pcg32_fast : public random_pcg32_fast_base - { - public: - using result_type = std::uint32_t; - - static constexpr random_pcg32_fast_base::internal_type default_seed = static_cast(0xCAFEF00DD15EA5E5ULL); - - explicit random_pcg32_fast(const random_pcg32_fast_base::internal_type state = default_seed) - : random_pcg32_fast_base(state), - my_inc (default_increment), - my_state(bump(state + increment())) { } - - random_pcg32_fast(const random_pcg32_fast& other) - : random_pcg32_fast_base(other), - my_inc (other.my_inc), - my_state(other.my_state) { } - - virtual ~random_pcg32_fast() = default; - - random_pcg32_fast& operator=(const random_pcg32_fast& other) - { - static_cast(random_pcg32_fast_base::operator=(other)); - - if(this != &other) - { - my_inc = other.my_inc; - my_state = other.my_state; - } - - return *this; - } - - void seed(const random_pcg32_fast_base::internal_type state = default_seed) - { - my_inc = default_increment; - - my_state = bump(state + increment()); - } - - result_type operator()() - { - const result_type value = output(base_generate0()); - - return value; - } - - static random_pcg32_fast::result_type (min)() { return (std::numeric_limits::min)(); } - static random_pcg32_fast::result_type (max)() { return (std::numeric_limits::max)(); } - - private: - static constexpr random_pcg32_fast_base::internal_type default_multiplier = static_cast(6364136223846793005ULL); - static constexpr random_pcg32_fast_base::internal_type default_increment = static_cast(1442695040888963407ULL); - - random_pcg32_fast_base::internal_type my_inc; - random_pcg32_fast_base::internal_type my_state; - - static internal_type multiplier() { return default_multiplier; } - - static internal_type increment () { return default_increment; } - - internal_type bump(const random_pcg32_fast_base::internal_type state) - { - return random_pcg32_fast_base::internal_type(state * multiplier()) + increment(); - } - - internal_type base_generate0() - { - const random_pcg32_fast_base::internal_type old_state = my_state; - - my_state = bump(my_state); - - return old_state; - } - }; - - } // namespace util - -#endif // UTIL_RANDOM_PCG32_2020_01_17_H_ diff --git a/examples/chapter11_07/src/util/utility/util_stopwatch.h b/examples/chapter11_07/src/util/utility/util_stopwatch.h index a6f7951fa..a5cc101f0 100644 --- a/examples/chapter11_07/src/util/utility/util_stopwatch.h +++ b/examples/chapter11_07/src/util/utility/util_stopwatch.h @@ -1,12 +1,14 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. +// Copyright Christopher Kormanyos 2014 - 2024. // 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) // -#ifndef UTIL_STOPWATCH_2014_01_07_H_ - #define UTIL_STOPWATCH_2014_01_07_H_ +#ifndef UTIL_STOPWATCH_2014_01_07_H + #define UTIL_STOPWATCH_2014_01_07_H + + #include namespace util { @@ -14,17 +16,21 @@ class stopwatch final { public: - typedef typename clock_type::duration duration_type; + using duration_type = typename clock_type::duration; + + using time_point_type = typename clock_type::time_point; stopwatch() : my_start(clock_type::now()) { } - stopwatch(typename clock_type::time_point start) : my_start(start) { } + explicit stopwatch(time_point_type start) : my_start(start) { } stopwatch(const stopwatch& other) : my_start(other.my_start) { } - ~stopwatch() { } + stopwatch(stopwatch&& other) noexcept : my_start(other.my_start) { } - stopwatch& operator=(const stopwatch& other) + ~stopwatch() = default; + + auto operator=(const stopwatch& other) -> stopwatch& { if(this != &other) { @@ -34,18 +40,25 @@ return *this; } - duration_type elapsed() const + auto operator=(stopwatch&& other) noexcept -> stopwatch& + { + my_start = other.my_start; + + return *this; + } + + auto elapsed() const -> duration_type { return clock_type::now() - my_start; } - void reset() + auto reset() -> void { my_start = clock_type::now(); } private: - typename clock_type::time_point my_start; + time_point_type my_start; }; } @@ -53,4 +66,4 @@ // const auto elapsed = std::chrono::duration_cast(my_stopwatch.elapsed()).count(); // const auto elapsed = std::chrono::duration_cast>(my_stopwatch.elapsed()).count(); -#endif // UTIL_STOPWATCH_2014_01_07_H_ +#endif // UTIL_STOPWATCH_2014_01_07_H diff --git a/examples/chapter11_07/src/util/utility/util_swdm.h b/examples/chapter11_07/src/util/utility/util_swdm.h index bce7da4c1..3e95bc48e 100644 --- a/examples/chapter11_07/src/util/utility/util_swdm.h +++ b/examples/chapter11_07/src/util/utility/util_swdm.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// \author (c) Marco Paland (info@paland.com) +// \author (c) Marco Paland (info (AT) paland.com) // 2014-2016, PALANDesign Hannover, Germany // // \license The MIT License (MIT) @@ -98,7 +98,7 @@ // void swdm::set_line(bool value) const // { // set the state of the according swdm line/pin to value (true = high/idle, false = low) -// if you don't use an open collector driver, you MUST config the pin as input for high/idle levels +// if you don't use an open collector driver, you MUST configure the pin as input for high/idle levels // and before setting the line to false/low it must be configured as an output. // } // @@ -128,13 +128,42 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifndef UTIL_SWDM_2016_04_11_H_ -#define UTIL_SWDM_2016_04_11_H_ +#ifndef UTIL_SWDM_2016_04_11_H +#define UTIL_SWDM_2016_04_11_H + +#if defined(__has_include) + #if(__has_include()) + #include + + #define UTIL_SWDM_HAS_USER_DEFINED_PORT + #endif +#endif -#include -#include #include +#include + +#if !defined(UTIL_SWDM_HAS_USER_DEFINED_PORT) +class dummy_port +{ + public: + static constexpr auto set_direction_output() noexcept -> void { } + static constexpr auto set_direction_input () noexcept -> void { } + static constexpr auto set_pin_high () noexcept -> void { } + static constexpr auto set_pin_low () noexcept -> void { } + static constexpr auto read_input_value () noexcept -> bool { return false; } + static constexpr auto toggle_pin () noexcept -> void { } +}; + +namespace mcal { namespace debug { + +using debug_monitor_port_type = dummy_port; + +} // namespace debug +} // namespace mcal + +#endif + // Defines the oversampling rate // The effective baud rate is the service_tick_rate / SWD_OVERSAMPLING_COUNT // For a service_tick_rate of 1 ms, the baud rate is 250 for 4 times oversampling @@ -699,8 +728,8 @@ class swdm : private util::noncopyable } private: - static const std::uint_fast8_t request_sync_field = UINT8_C(0x55); // Request sync field - static const std::uint_fast8_t response_sync_field = UINT8_C(0xAA); // Response sync field + static constexpr std::uint_fast8_t request_sync_field = UINT8_C(0x55); // Request sync field + static constexpr std::uint_fast8_t response_sync_field = UINT8_C(0xAA); // Response sync field typedef enum enum_state_type { @@ -744,4 +773,4 @@ class swdm : private util::noncopyable } // namespace util -#endif // UTIL_SWDM_2016_04_11_H_ +#endif // UTIL_SWDM_2016_04_11_H diff --git a/examples/chapter11_07/src/util/utility/util_time.h b/examples/chapter11_07/src/util/utility/util_time.h index 682f97ada..d59eae556 100644 --- a/examples/chapter11_07/src/util/utility/util_time.h +++ b/examples/chapter11_07/src/util/utility/util_time.h @@ -1,116 +1,115 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2014. +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_TIME_2010_04_10_H_ - #define UTIL_TIME_2010_04_10_H_ +#ifndef UTIL_TIME_2010_04_10_H + #define UTIL_TIME_2010_04_10_H + + #include + #include #include #include - #include - #include namespace util { template class timer { + private: + static constexpr auto timer_mask = + static_cast + ( + (UINTMAX_C(1) << static_cast(std::numeric_limits::digits - 1)) - UINTMAX_C(1) + ); + public: - typedef unsigned_tick_type tick_type; + using tick_type = unsigned_tick_type; - static_assert(std::numeric_limits::is_signed == false, - "the timer tick_type must be unsigned"); + template static constexpr auto microseconds(other_tick_type value_microseconds) noexcept -> tick_type { return static_cast(value_microseconds); } + template static constexpr auto milliseconds(other_tick_type value_milliseconds) noexcept -> tick_type { return static_cast(UINT16_C(1000)) * microseconds(value_milliseconds); } + template static constexpr auto seconds (other_tick_type value_seconds) noexcept -> tick_type { return static_cast(UINT16_C(1000)) * milliseconds(value_seconds ); } + template static constexpr auto minutes (other_tick_type value_minutes) noexcept -> tick_type { return static_cast(UINT16_C( 60)) * seconds (value_minutes ); } + template static constexpr auto hours (other_tick_type value_hours) noexcept -> tick_type { return static_cast(UINT16_C( 60)) * minutes (value_hours ); } + template static constexpr auto days (other_tick_type value_days) noexcept -> tick_type { return static_cast(UINT16_C( 24)) * hours (value_days ); } + template static constexpr auto weeks (other_tick_type value_weeks) noexcept -> tick_type { return static_cast(UINT16_C( 7)) * days (value_weeks ); } - static_assert(std::numeric_limits::digits <= std::numeric_limits::digits, - "The width of the timer tick_type can not exceed the width of mcal::gpt::value_type"); + constexpr timer() = default; - private: - static const tick_type timer_mask = static_cast((UINTMAX_C(1) << (std::numeric_limits::digits - 1)) - UINTMAX_C(1)); + explicit constexpr timer(tick_type tick_value) : my_tick(my_now() + tick_value) { } - public: - template static constexpr tick_type microseconds(other_tick_type value_microseconds) { return value_microseconds; } - template static constexpr tick_type milliseconds(other_tick_type value_milliseconds) { return static_cast(1000UL) * microseconds(value_milliseconds); } - template static constexpr tick_type seconds (other_tick_type value_seconds ) { return static_cast(1000UL) * milliseconds(value_seconds ); } - template static constexpr tick_type minutes (other_tick_type value_minutes ) { return static_cast( 60UL) * seconds (value_minutes ); } - template static constexpr tick_type hours (other_tick_type value_hours ) { return static_cast( 60UL) * minutes (value_hours ); } - template static constexpr tick_type days (other_tick_type value_days ) { return static_cast( 24UL) * hours (value_days ); } - template static constexpr tick_type weeks (other_tick_type value_weeks ) { return static_cast( 7UL) * days (value_weeks ); } + constexpr timer(const timer& other) = default; - timer() : my_tick(0U) { } + constexpr timer(timer&& other) noexcept = default; - timer(const tick_type& tick_value) : my_tick(my_now() + tick_value) { } + ~timer() = default; - timer(const timer& other) : my_tick(other.my_tick) { } + auto operator=(const timer& other) -> timer& = default; - timer& operator=(const timer& other) - { - if(this != &other) - { - my_tick = other.my_tick; - } + auto operator=(timer&& other) noexcept -> timer& = default; - return *this; - } - - void start_interval(const tick_type& tick_value) + auto start_interval(const tick_type& tick_value) -> void { my_tick += tick_value; } - void start_relative(const tick_type& tick_value) + auto start_relative(const tick_type& tick_value) -> void { my_tick = my_now() + tick_value; } - bool timeout() const + constexpr auto timeout() const -> bool { - const tick_type delta = my_now() - my_tick; - - return (delta <= timer_mask); + return (static_cast(my_now() - my_tick) <= timer_mask); } - bool timeout_of_specific_timepoint(const tick_type timepoint) const + constexpr auto timeout_of_specific_timepoint(const tick_type timepoint) const -> bool { - const tick_type delta = timepoint - my_tick; - - return (delta <= timer_mask); + return (static_cast(timepoint - my_tick) <= timer_mask); } - void set_mark() + auto set_mark() -> void { - my_tick = my_now(); - - return my_tick; + return (my_tick = my_now()); } - static tick_type get_mark() + static constexpr auto get_mark() -> tick_type { return my_now(); } - tick_type get_ticks_since_mark() const + constexpr auto get_ticks_since_mark() const -> tick_type { return my_now() - my_tick; } - static void blocking_delay(const tick_type& delay) + static auto blocking_delay(const tick_type& delay) -> void { - const timer t_delay(delay); + const timer t_delay { delay }; // NOLINT(altera-id-dependent-backward-branch) - while(false == t_delay.timeout()) + while(!t_delay.timeout()) // NOLINT(altera-id-dependent-backward-branch) { - mcal::cpu::nop(); + mcal::wdg::secure::trigger(); } } private: - tick_type my_tick; + tick_type my_tick { my_now() }; + + constexpr static auto my_now() -> tick_type + { + return static_cast(mcal::gpt::secure::get_time_elapsed()); + } + + static_assert((!std::numeric_limits::is_signed), + "the timer tick_type must be unsigned"); - static tick_type my_now() { return static_cast(mcal::gpt::secure::get_time_elapsed()); } + static_assert(std::numeric_limits::digits <= std::numeric_limits::digits, + "The width of the timer tick_type can not exceed the width of mcal::gpt::value_type"); }; - } + } // namespace util -#endif // UTIL_TIME_2010_04_10_H_ +#endif // UTIL_TIME_2010_04_10_H diff --git a/examples/chapter11_07/src/util/utility/util_two_part_data_manipulation.h b/examples/chapter11_07/src/util/utility/util_two_part_data_manipulation.h index a27077d74..282b5e6e6 100644 --- a/examples/chapter11_07/src/util/utility/util_two_part_data_manipulation.h +++ b/examples/chapter11_07/src/util/utility/util_two_part_data_manipulation.h @@ -1,28 +1,29 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H_ - #define UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H_ +#ifndef UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H + #define UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H - #include #include + #include + namespace util { template(std::numeric_limits::digits * 2)>::exact_type> - inline unsigned_long_type make_long(unsigned_short_type lo, unsigned_short_type hi) + inline constexpr auto make_long(unsigned_short_type lo, unsigned_short_type hi) -> unsigned_long_type { // Ensure that the unsigned_short_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_short_type of the make_long template must be an integer type"); // Ensure that the unsigned_long_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_long_type of the make_long template must be an integer type."); // Ensure that the unsigned_long_type has exactly twice the digits as the unsigned_short_type. @@ -30,11 +31,11 @@ "the unsigned_long_type of the make_long template must be twice as wide as the unsigned_short_type"); // Ensure that the unsigned_short_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the unsigned_short_type of the make_long template must be unsigned"); // Ensure that the unsigned_long_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the unsigned_long_type of the make_long template must be unsigned."); return static_cast(static_cast(static_cast(hi) << std::numeric_limits::digits) | lo); @@ -42,14 +43,14 @@ template(std::numeric_limits::digits * 2)>::exact_type> - inline unsigned_short_type lo_part(unsigned_long_type val) + inline constexpr auto lo_part(unsigned_long_type val) -> unsigned_short_type { // Ensure that the unsigned_short_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_short_type of the make_long template must be an integer type"); // Ensure that the unsigned_long_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_long_type of the make_long template must be an integer type."); // Ensure that the unsigned_long_type has exactly twice the digits as the unsigned_short_type. @@ -57,11 +58,11 @@ "the unsigned_long_type of the lo_part template must be twice as wide as the unsigned_short_type"); // Ensure that the unsigned_short_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the unsigned_short_type of the lo_part template must be unsigned"); // Ensure that the unsigned_long_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the long type of the lo_part template must be unsigned"); return static_cast(val); @@ -69,14 +70,14 @@ template(std::numeric_limits::digits * 2)>::exact_type> - inline unsigned_short_type hi_part(unsigned_long_type val) + inline constexpr auto hi_part(unsigned_long_type val) -> unsigned_short_type { // Ensure that the unsigned_short_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_short_type of the make_long template must be an integer type"); // Ensure that the unsigned_long_type is an integer type. - static_assert(std::numeric_limits::is_integer == true, + static_assert(std::numeric_limits::is_integer, "the unsigned_long_type of the make_long template must be an integer type."); // Ensure that the unsigned_long_type has exactly twice the digits as the unsigned_short_type. @@ -84,15 +85,15 @@ "the unsigned_long_type of the hi_part template must be twice as wide as the unsigned_short_type"); // Ensure that the unsigned_short_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the unsigned_short_type of the hi_part template must be unsigned"); // Ensure that the unsigned_long_type is unsigned. - static_assert(std::numeric_limits::is_signed == false, + static_assert((!std::numeric_limits::is_signed), "the unsigned_long_type of the hi_part template must be unsigned"); return static_cast(val >> std::numeric_limits::digits); } } -#endif // UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H_ +#endif // UTIL_TWO_PART_DATA_MANIPULATION_2010_06_13_H diff --git a/examples/chapter11_07/src/util/utility/util_utype_helper.h b/examples/chapter11_07/src/util/utility/util_utype_helper.h index f009a0ff4..e6040965a 100644 --- a/examples/chapter11_07/src/util/utility/util_utype_helper.h +++ b/examples/chapter11_07/src/util/utility/util_utype_helper.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) // -#ifndef UTIL_UTYPE_HELPER_2012_01_23_H_ - #define UTIL_UTYPE_HELPER_2012_01_23_H_ +#ifndef UTIL_UTYPE_HELPER_2012_01_23_H + #define UTIL_UTYPE_HELPER_2012_01_23_H #include @@ -17,44 +17,44 @@ static_assert(utype_bit_count <= 64U, "the bit count of the unsigned type can not exceed 64"); - typedef std::uint64_t exact_type; + using exact_type = std::uint64_t; }; - template<> struct utype_helper<0U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<1U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<2U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<3U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<4U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<5U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<6U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<7U> { typedef std::uint8_t exact_type; }; - template<> struct utype_helper<8U> { typedef std::uint8_t exact_type; }; - - template<> struct utype_helper<9U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<10U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<11U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<12U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<13U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<14U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<15U> { typedef std::uint16_t exact_type; }; - template<> struct utype_helper<16U> { typedef std::uint16_t exact_type; }; - - template<> struct utype_helper<17U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<18U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<19U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<20U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<21U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<22U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<23U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<24U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<25U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<26U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<27U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<28U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<29U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<30U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<31U> { typedef std::uint32_t exact_type; }; - template<> struct utype_helper<32U> { typedef std::uint32_t exact_type; }; + template<> struct utype_helper<0U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<1U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<2U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<3U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<4U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<5U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<6U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<7U> { using exact_type = std::uint8_t; }; + template<> struct utype_helper<8U> { using exact_type = std::uint8_t; }; + + template<> struct utype_helper<9U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<10U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<11U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<12U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<13U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<14U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<15U> { using exact_type = std::uint16_t; }; + template<> struct utype_helper<16U> { using exact_type = std::uint16_t; }; + + template<> struct utype_helper<17U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<18U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<19U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<20U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<21U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<22U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<23U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<24U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<25U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<26U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<27U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<28U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<29U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<30U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<31U> { using exact_type = std::uint32_t; }; + template<> struct utype_helper<32U> { using exact_type = std::uint32_t; }; } -#endif // UTIL_UTYPE_HELPER_2012_01_23_H_ +#endif // UTIL_UTYPE_HELPER_2012_01_23_H diff --git a/examples/chapter11_07/target/app/make/app_make.gmk b/examples/chapter11_07/target/app/make/app_make.gmk index 436cd02dd..9bcc14d94 100644 --- a/examples/chapter11_07/target/app/make/app_make.gmk +++ b/examples/chapter11_07/target/app/make/app_make.gmk @@ -6,7 +6,7 @@ # # ------------------------------------------------------------------------------ -# +# # Makefile # # Build file for the reference application using the GNU tools @@ -15,24 +15,57 @@ # # 07-April-2010 # +# See also a definitive list of GCC command line options +# (for numerous target systems) here: +# https://man7.org/linux/man-pages/man1/gcc.1.html +# # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -# compiler location, build from GCC version and GCC target +# operating system # ------------------------------------------------------------------------------ -COMPILER_DIRECTORY = gcc-$(GCC_VERSION)-$(GCC_TARGET) + +ifeq ($(TYP_OS),) + +ifeq ($(OS),Windows_NT) +TYP_OS := WIN +else +TYP_OS := NIX +endif + +endif # ------------------------------------------------------------------------------ -# paths +# punctuation +# ------------------------------------------------------------------------------ + +DQUOTE := \" +$(DQUOTE) := \" + +SEMICOLON := ; +$(SEMICOLON) := ; + +DOLLAR := $$ +$(DOLLAR) := $$ + +# ------------------------------------------------------------------------------ +# null device # ------------------------------------------------------------------------------ -PATH_TOOLS = tools -PATH_TOOLS_UTIL = $(PATH_TOOLS)\Util -PATH_TOOLS_MINGW = $(PATH_TOOLS_UTIL)\msys64\usr -PATH_TOOLS_MINGW_BIN = $(PATH_TOOLS_MINGW)\bin -PATH_TOOLS_CC = $(PATH_TOOLS_MINGW)\local\gcc-$(GCC_VERSION)-$(GCC_TARGET)\bin +ifeq ($(TYP_OS),WIN) +NULL_DEVICE := NUL +$(NULL_DEVICE) := NUL +else +NULL_DEVICE := /dev/null +$(NULL_DEVICE) := /dev/null +endif + + +# ------------------------------------------------------------------------------ +# paths +# ------------------------------------------------------------------------------ PATH_APP = src PATH_TGT = target/micros/$(TGT) PATH_APP_MAKE = target/app/make @@ -40,16 +73,41 @@ PATH_TGT_MAKE = $(PATH_TGT)/make PATH_BIN = bin PATH_TMP = tmp PATH_OBJ = $(PATH_TMP)/obj -PATH_SRC = $(PATH_TMP)/src +PATH_LST = $(PATH_TMP)/lst PATH_ERR = $(PATH_TMP)/err # ------------------------------------------------------------------------------ -# include files +# standard shell tools # ------------------------------------------------------------------------------ -include $(PATH_APP_MAKE)/app_files.gmk # Application file list -include $(PATH_TGT_MAKE)/$(TGT)_files.gmk # Target filelist -include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags + +ifeq ($(TYP_OS),WIN) + +PATH_TOOLS = tools +PATH_TOOLS_UTIL = $(PATH_TOOLS)\Util +PATH_TOOLS_MINGW = $(PATH_TOOLS_UTIL)\msys64\usr +PATH_TOOLS_MINGW_BIN = $(PATH_TOOLS_MINGW)\bin +PATH_TOOLS_CC = $(PATH_TOOLS_MINGW)\local\gcc-$(GCC_VERSION)-$(GCC_TARGET)\bin + +ECHO = $(PATH_TOOLS_MINGW_BIN)\echo.exe +MAKE = $(PATH_TOOLS_MINGW_BIN)\make.exe +MKDIR = $(PATH_TOOLS_MINGW_BIN)\mkdir.exe +RM = $(PATH_TOOLS_MINGW_BIN)\rm.exe +SED = $(PATH_TOOLS_MINGW_BIN)\sed.exe + +else + +ECHO = echo +MAKE = make +MKDIR = mkdir +RM = rm +SED = sed + +ifneq ($(MY_GMAKE),) +MAKE := $(MY_GMAKE) +endif + +endif # ------------------------------------------------------------------------------ @@ -57,17 +115,32 @@ include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags # ------------------------------------------------------------------------------ APP = $(PATH_BIN)/chapter11_07 +IMAGE_FILE = $(APP).bin + +RULE_SPECIAL_MAKE_IMAGE_FILE = +RULE_SPECIAL_MAKE_FLASH_BATCH = + +WARN_FLAGS := + # ------------------------------------------------------------------------------ -# object files +# linker definition file # ------------------------------------------------------------------------------ -FILES_TMP = $(FILES_CPP) $(FILES_TGT) -FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_TMP)))) +LINKER_DEFINITION_FILE := $(PATH_TGT_MAKE)/$(TGT).ld # ------------------------------------------------------------------------------ -# linker definition file +# include the target-specific make files # ------------------------------------------------------------------------------ -LINKER_DEFINITION_FILE = $(PATH_TGT_MAKE)/$(TGT).ld +include $(PATH_APP_MAKE)/app_files.gmk # Application file list +include $(PATH_TGT_MAKE)/$(TGT)_files.gmk # Target filelist +include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags + + +# ------------------------------------------------------------------------------ +# object files +# ------------------------------------------------------------------------------ +FILES_TMP = $(FILES_CPP) $(FILES_TGT) +FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_TMP)))) # ------------------------------------------------------------------------------ @@ -85,51 +158,94 @@ VPATH := $(sort $(dir $(FILES_TMP))) # ------------------------------------------------------------------------------ # Development tools # ------------------------------------------------------------------------------ +ifeq ($(TYP_OS),WIN) + ifeq ($(GCC_PREFIX),) -AR = $(PATH_TOOLS_CC)\ar.exe -AS = $(PATH_TOOLS_CC)\g++.exe -CC = $(PATH_TOOLS_CC)\g++.exe -CPPFILT = $(PATH_TOOLS_CC)\c++filt.exe -NM = $(PATH_TOOLS_CC)\nm.exe -OBJDUMP = $(PATH_TOOLS_CC)\objdump.exe -OBJCOPY = $(PATH_TOOLS_CC)\objcopy.exe -READELF = $(PATH_TOOLS_CC)\readelf.exe -SIZE = $(PATH_TOOLS_CC)\size.exe + +ifeq ($(AR),) +AR := $(PATH_TOOLS_CC)\ar.exe +endif +ifeq ($(AS),) +AS := $(PATH_TOOLS_CC)\g++.exe +endif +ifeq ($(CC),) +CC := $(PATH_TOOLS_CC)\g++.exe +endif +ifeq ($(CPPFILT),) +CPPFILT := $(PATH_TOOLS_CC)\c++filt.exe +endif +ifeq ($(NM),) +NM := $(PATH_TOOLS_CC)\nm.exe +endif +ifeq ($(OBJDUMP),) +OBJDUMP := $(PATH_TOOLS_CC)\objdump.exe +endif +ifeq ($(OBJCOPY),) +OBJCOPY := $(PATH_TOOLS_CC)\objcopy.exe +endif +ifeq ($(READELF),) +READELF := $(PATH_TOOLS_CC)\readelf.exe +endif +ifeq ($(SIZE),) +SIZE := $(PATH_TOOLS_CC)\size.exe +endif + else -AR = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-ar.exe -AS = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe -CC = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe -CPPFILT = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-c++filt.exe -NM = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-nm.exe -OBJDUMP = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objdump.exe -OBJCOPY = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objcopy.exe -READELF = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-readelf.exe -SIZE = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-size.exe + +AR := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-ar.exe +AS := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe +CC := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe +CPPFILT := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-c++filt.exe +NM := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-nm.exe +OBJDUMP := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objdump.exe +OBJCOPY := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objcopy.exe +READELF := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-readelf.exe +SIZE := $(PATH_TOOLS_CC)\$(GCC_PREFIX)-size.exe endif -ECHO = $(PATH_TOOLS_MINGW_BIN)\echo.exe -MAKE = $(PATH_TOOLS_MINGW_BIN)\make.exe -MKDIR = $(PATH_TOOLS_MINGW_BIN)\mkdir.exe -RM = $(PATH_TOOLS_MINGW_BIN)\rm.exe -SED = $(PATH_TOOLS_MINGW_BIN)\sed.exe +else + +ifeq ($(GCC_PREFIX),) +AR := ar +AS := g++ +CC := g++ +CPPFILT := c++filt +NM := nm +OBJDUMP := objdump +OBJCOPY := objcopy +READELF := readelf +SIZE := size +else +AR := $(GCC_PREFIX)-ar +AS := $(GCC_PREFIX)-g++ +CC := $(GCC_PREFIX)-g++ +CPPFILT := $(GCC_PREFIX)-c++filt +NM := $(GCC_PREFIX)-nm +OBJDUMP := $(GCC_PREFIX)-objdump +OBJCOPY := $(GCC_PREFIX)-objcopy +READELF := $(GCC_PREFIX)-readelf +SIZE := $(GCC_PREFIX)-size +endif + +endif # ------------------------------------------------------------------------------ # Tool parameters # ------------------------------------------------------------------------------ -C_INCLUDES = $(TGT_INCLUDES) \ - -I$(PATH_APP) \ - -I$(PATH_APP)/mcal/$(TGT) \ - -I$(PATH_APP)/os/FreeRTOS/Source/include +C_INCLUDES = $(TGT_INCLUDES) \ + -I$(PATH_APP) \ + -I$(PATH_APP)/mcal/$(TGT) + +ifeq ($(WARN_FLAGS),) -GCCFLAGS = $(TGT_CFLAGS) \ - -Wall \ +WARN_FLAGS = -Wall \ -Wextra \ - -pedantic \ + -Wpedantic \ -Wmain \ -Wundef \ - -Wsign-conversion \ -Wconversion \ + -Wsign-conversion \ -Wunused-parameter \ -Wuninitialized \ -Wmissing-declarations \ @@ -141,44 +257,40 @@ GCCFLAGS = $(TGT_CFLAGS) \ -Wmissing-include-dirs \ -Winit-self \ -Wfloat-equal \ - -Wdouble-promotion \ + -Wdouble-promotion + +endif + +GCCFLAGS = -g \ + $(WARN_FLAGS) \ + -Wno-comment \ -gdwarf-2 \ -fno-exceptions \ - -ffunction-sections \ -fdata-sections \ - -flto + -ffunction-sections CFLAGS = $(GCCFLAGS) \ - -Wno-int-to-pointer-cast \ - -Wno-pointer-to-int-cast \ - -Wunsuffixed-float-constants \ - -x c \ - -std=gnu99 - -CPPFLAGS = $(GCCFLAGS) \ - $(TGT_CPPFLAGS) \ + $(TGT_CFLAGS) \ + -x c + +CXXFLAGS = $(GCCFLAGS) \ + $(TGT_CXXFLAGS) \ -x c++ \ -fno-rtti \ - -fstrict-enums \ -fno-use-cxa-atexit \ - -fno-use-cxa-get-exception-ptr \ - -fno-nonansi-builtins \ -fno-threadsafe-statics \ - -fno-enforce-eh-specs \ - -ftemplate-depth=32 \ + -ftemplate-depth=128 \ -Wzero-as-null-pointer-constant AFLAGS = $(GCCFLAGS) \ - $(TGT_CFLAGS) \ + $(TGT_CXXFLAGS) \ $(TGT_AFLAGS) \ -x assembler -LDFLAGS = $(GCCFLAGS) \ +LDFLAGS = $(CXXFLAGS) \ $(TGT_LDFLAGS) \ -x none \ - -flto \ - -Wl,--gc-sections \ - -Wl,-Map,$(APP).map + -Wl,--print-memory-usage # ------------------------------------------------------------------------------ # Main-Dependencies (app: all) @@ -203,8 +315,8 @@ clean_prj: @-$(MKDIR) -p $(PATH_BIN) @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) - @-$(MKDIR) -p $(PATH_SRC) - @-$(RM) -r $(PATH_BIN) > NUL 2> NUL + @-$(MKDIR) -p $(PATH_LST) + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -217,11 +329,11 @@ clean_all: @-$(MKDIR) -p $(PATH_BIN) @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) - @-$(MKDIR) -p $(PATH_SRC) - @-$(RM) -r $(PATH_OBJ) > NUL 2> NUL - @-$(RM) -r $(PATH_ERR) > NUL 2> NUL - @-$(RM) -r $(PATH_SRC) > NUL 2> NUL - @-$(RM) -r $(PATH_BIN) > NUL 2> NUL + @-$(MKDIR) -p $(PATH_LST) + @-$(RM) -r $(PATH_OBJ) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_ERR) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_LST) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -231,21 +343,27 @@ clean_all: .PHONY: version version: # Print the GNU make version and the compiler version + @$(ECHO) @$(ECHO) +++ Print GNUmake version @$(MAKE) --version @$(ECHO) - @$(ECHO) +++ Print GCC version + @$(ECHO) +++ Print compiler version @$(CC) -v @$(ECHO) @$(ECHO) +++ Print compiler include paths @$(ECHO) $(C_INCLUDES) @$(ECHO) +ifeq ($(TYP_OS),WIN) @$(ECHO) +++ Print compiler include paths (for VisualStudio(R) browsing) - @$(ECHO) $(subst /,\, $(subst -I,$$\(SolutionDir\), $(C_INCLUDES))) + @$(ECHO) $(addsuffix $(SEMICOLON),$(subst -I,$$\(ProjectDir\)/, $(C_INCLUDES))) @$(ECHO) +endif @$(ECHO) +++ Print compiler definitions @$(ECHO) $(C_DEFINES) @$(ECHO) + @$(ECHO) +++ Print compiler CXXFLAGS flags + @$(ECHO) $(CXXFLAGS) + @$(ECHO) # ------------------------------------------------------------------------------ @@ -254,8 +372,6 @@ version: $(APP).$(TGT_SUFFIX) : $(LINKER_DEFINITION_FILE) $(FILES_O) @-$(ECHO) +++ linking application to generate: $(APP).$(TGT_SUFFIX) @-$(CC) $(LDFLAGS) $(FILES_O) -o $(APP).$(TGT_SUFFIX) - @-$(ECHO) +++ generating assembly list file: $(APP).lss - @-$(OBJDUMP) --disassemble $(APP).$(TGT_SUFFIX) > $(APP).lss # ------------------------------------------------------------------------------ @@ -280,9 +396,31 @@ endif # create hex mask # ------------------------------------------------------------------------------ $(APP)_flash.hex : $(APP).$(TGT_SUFFIX) - @-$(ECHO) +++ creating hex module: $(APP).hex. - @-$(OBJCOPY) -O ihex $(APP).$(TGT_SUFFIX) $(APP).hex - @-$(OBJCOPY) -S -O binary $(APP).$(TGT_SUFFIX) $(APP).bin + @-$(ECHO) +++ creating hex module: $(APP).$(TGT_SUFFIX) +ifeq ($(TGT_SUFFIX),elf) + @-$(ECHO) +++ creating hex module: $(APP).hex + @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O ihex $(APP).hex + @-$(ECHO) +++ creating srec module: $(APP).s19 + @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O srec $(APP).s19 + @-$(ECHO) +++ creating disassembly listing: $(APP)_disassembly.txt + @-$(OBJDUMP) -D $(APP).$(TGT_SUFFIX) > $(APP)_disassembly.txt +else + @-$(ECHO) +++ creating hex module disabled for non-ELF absolute objet file. +endif +ifeq ($(RULE_SPECIAL_MAKE_IMAGE_FILE),) + @-$(ECHO) +++ creating special image file + @-$(ECHO) +++ disabled because there is no special image file +else + @-$(ECHO) +++ creating special image file + @-$(RULE_SPECIAL_MAKE_IMAGE_FILE) +endif +ifeq ($(RULE_SPECIAL_MAKE_FLASH_BATCH),) + @-$(ECHO) +++ creating special flash batch file + @-$(ECHO) +++ disabled because there is no special flash batch file +else + @-$(ECHO) +++ creating special flash batch file + @-$(RULE_SPECIAL_MAKE_FLASH_BATCH) +endif # ------------------------------------------------------------------------------ # Dependencyfile include (build) @@ -291,7 +429,7 @@ $(APP)_flash.hex : $(APP).$(TGT_SUFFIX) # If the files do not exist then the includes will be ignored. # ------------------------------------------------------------------------------ ifneq ($(MAKECMDGOALS),rebuild) --include $(subst .o,.d,$(FILES_O)) # for example tmp/obj/sys_start.d, tmp/obj/mcal_cpu.d, etc +-include $(subst .o,.d,$(FILES_O)) endif diff --git a/examples/chapter11_07/target/app/make/app_rules.gmk b/examples/chapter11_07/target/app/make/app_rules.gmk index 9a0de5e83..8737bc559 100644 --- a/examples/chapter11_07/target/app/make/app_rules.gmk +++ b/examples/chapter11_07/target/app/make/app_rules.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2018. +# Copyright Christopher Kormanyos 2007 - 2024. # 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) @@ -11,13 +11,20 @@ # # Generic pattern rules # -# Based on GNU Make 3.81 +# Based on GNU Make 4.2.1 # # 07-April-2010 # # ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +# GCC dependency flags. +# ------------------------------------------------------------------------------ + +DEP_FLAGS := -MMD -MF $(PATH_OBJ)/$(basename $(@F)).d + + # ------------------------------------------------------------------------------ # Rule to compile C++ source file (*.cpp) to object file (*.o). # ------------------------------------------------------------------------------ @@ -30,12 +37,29 @@ $(PATH_OBJ)/%.o : %.cpp # ...and create an assembly listing using objdump, # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. - @-$(CC) $(CPPFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S -C $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst - @-$(ECHO) -n $(PATH_OBJ)/ > $(PATH_OBJ)/$(basename $(@F)).d - @-$(CC) $(CPPFLAGS) $< -MM >> $(PATH_OBJ)/$(basename $(@F)).d + @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cpp:\([0-9]*\),|.cpp(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif + +# ------------------------------------------------------------------------------ +# Rule to compile C++ source file (*.cc) to object file (*.o). +# ------------------------------------------------------------------------------ +$(PATH_OBJ)/%.o : %.cc + @$(ECHO) +++ compile: $< to $@ + # Compile the source file, + # ...and reformat (using sed) any possible error/warning messages + # for the VisualStudio(R) output window, + # ...and create an assembly listing using objdump, + # ...and generate a dependency file (using the -MM flag), + # ...and be sure to include the path in the dependency file. + @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cc:\([0-9]*\),|.cc(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif # ------------------------------------------------------------------------------ # Rule to compile C source file (*.c) to object file (*.o). @@ -49,11 +73,9 @@ $(PATH_OBJ)/%.o : %.c # ...and create an assembly listing using objdump, # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. - @-$(CC) $(CFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst - @-$(ECHO) -n $(PATH_OBJ)/ > $(PATH_OBJ)/$(basename $(@F)).d - @-$(CC) $(CFLAGS) $< -MM >> $(PATH_OBJ)/$(basename $(@F)).d + @-$(CC) $(CFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.c:\([0-9]*\),|.c(\1) :|' $(PATH_ERR)/$(basename $(@F)).err + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst # ------------------------------------------------------------------------------ @@ -68,4 +90,4 @@ $(PATH_OBJ)/%.o : %.s # ...and create an assembly listing using objdump @-$(CC) $(AFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err @-$(SED) -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst diff --git a/examples/chapter11_07/target/micros/avr/make/avr.ld b/examples/chapter11_07/target/micros/avr/make/avr.ld index 1b7f023ec..005bbb1d2 100644 --- a/examples/chapter11_07/target/micros/avr/make/avr.ld +++ b/examples/chapter11_07/target/micros/avr/make/avr.ld @@ -1,6 +1,5 @@ - /* - Copyright Christopher Kormanyos 2007 - 2021. + Copyright Christopher Kormanyos 2007 - 2024. 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) diff --git a/examples/chapter11_07/target/micros/avr/make/avr_flags.gmk b/examples/chapter11_07/target/micros/avr/make/avr_flags.gmk index 2f1488987..7298f982e 100644 --- a/examples/chapter11_07/target/micros/avr/make/avr_flags.gmk +++ b/examples/chapter11_07/target/micros/avr/make/avr_flags.gmk @@ -9,30 +9,43 @@ # compiler flags for the target architecture # ------------------------------------------------------------------------------ -# See also: https://blog.zakkemble.net/avr-gcc-builds/ - +ifneq ($(MAKE),make) GCC_VERSION = 14.2.0 +endif GCC_TARGET = avr GCC_PREFIX = avr TGT_SUFFIX = elf -TGT_CFLAGS = -Os \ - -mmcu=atmega328p \ - -fsigned-char \ - -mrelax \ - -finline-functions \ - -finline-limit=64 - -TGT_CPPFLAGS = -std=c++11 - -TGT_INCLUDES = -I$(PATH_APP)/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 \ - -I$(PATH_APP)/os/FreeRTOS/Source/portable/GCC-ATmega328 \ +TGT_ALLFLAGS = -mmcu=atmega328p \ + -mrelax \ + -finline-functions \ + -finline-limit=64 \ + -fsigned-char + +ifeq ($(GCC_VERSION),14.2.0) +TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ + -mdouble=32 \ + -mlong-double=64 +endif + +TGT_CFLAGS = -O1 \ + -std=gnu11 \ + $(TGT_ALLFLAGS) + +TGT_CXXFLAGS = -Os \ + -std=c++14 \ + $(TGT_ALLFLAGS) + +TGT_INCLUDES = -I$(PATH_APP)/os/FreeRTOS/Source/include/cfg/GCC-ATMega328 \ + -I$(PATH_APP)/os/FreeRTOS/Source/portable/GCC-ATmega328 \ + -I$(PATH_APP)/os/FreeRTOS/Source/include \ -I$(PATH_APP)/util/STL TGT_AFLAGS = -TGT_LDFLAGS = -nostdlib \ - -nostartfiles \ +TGT_LDFLAGS = -nostdlib \ + -nostartfiles \ + -Wl,--gc-sections \ + -Wl,-Map,$(APP).map \ -T $(LINKER_DEFINITION_FILE) - diff --git a/examples/chapter11_07/target/micros/avr/startup/crt0.cpp b/examples/chapter11_07/target/micros/avr/startup/crt0.cpp index 8d4546809..e9bc0bae5 100644 --- a/examples/chapter11_07/target/micros/avr/startup/crt0.cpp +++ b/examples/chapter11_07/target/micros/avr/startup/crt0.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter11_07/target/micros/avr/startup/crt0_init_ram.cpp b/examples/chapter11_07/target/micros/avr/startup/crt0_init_ram.cpp index 4adb0aaf3..11d0c4eb5 100644 --- a/examples/chapter11_07/target/micros/avr/startup/crt0_init_ram.cpp +++ b/examples/chapter11_07/target/micros/avr/startup/crt0_init_ram.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter11_07/target/micros/avr/startup/crt1.cpp b/examples/chapter11_07/target/micros/avr/startup/crt1.cpp index 732533bf4..0a3ce7243 100644 --- a/examples/chapter11_07/target/micros/avr/startup/crt1.cpp +++ b/examples/chapter11_07/target/micros/avr/startup/crt1.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter11_07/target/micros/avr/startup/int_vect.cpp b/examples/chapter11_07/target/micros/avr/startup/int_vect.cpp index b175b0a2f..b408d9438 100644 --- a/examples/chapter11_07/target/micros/avr/startup/int_vect.cpp +++ b/examples/chapter11_07/target/micros/avr/startup/int_vect.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2021. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter16_08/target/micros/avr/make/avr.ld b/examples/chapter16_08/target/micros/avr/make/avr.ld index 28df3ab01..005bbb1d2 100644 --- a/examples/chapter16_08/target/micros/avr/make/avr.ld +++ b/examples/chapter16_08/target/micros/avr/make/avr.ld @@ -1,5 +1,5 @@ /* - Copyright Christopher Kormanyos 2007 - 2022. + Copyright Christopher Kormanyos 2007 - 2024. 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) diff --git a/examples/chapter16_08/target/micros/avr/make/avr_files.gmk b/examples/chapter16_08/target/micros/avr/make/avr_files.gmk index 43ac7b32c..68fb740b7 100644 --- a/examples/chapter16_08/target/micros/avr/make/avr_files.gmk +++ b/examples/chapter16_08/target/micros/avr/make/avr_files.gmk @@ -9,8 +9,8 @@ # File list of the avr files in the project # ------------------------------------------------------------------------------ -FILES_TGT = $(PATH_APP)/mcal/mcal_gcc_cxx_completion \ - $(PATH_TGT)/startup/crt0 \ - $(PATH_TGT)/startup/crt0_init_ram \ - $(PATH_TGT)/startup/crt1 \ +FILES_TGT = $(PATH_APP)/mcal/mcal_gcc_cxx_completion \ + $(PATH_TGT)/startup/crt0 \ + $(PATH_TGT)/startup/crt0_init_ram \ + $(PATH_TGT)/startup/crt1 \ $(PATH_TGT)/startup/int_vect diff --git a/examples/chapter16_08/target/micros/avr/startup/crt0.cpp b/examples/chapter16_08/target/micros/avr/startup/crt0.cpp index 0c73532a6..5e8f21cdf 100644 --- a/examples/chapter16_08/target/micros/avr/startup/crt0.cpp +++ b/examples/chapter16_08/target/micros/avr/startup/crt0.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2022. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter16_08/target/micros/avr/startup/crt0_init_ram.cpp b/examples/chapter16_08/target/micros/avr/startup/crt0_init_ram.cpp index eb20948b6..11d0c4eb5 100644 --- a/examples/chapter16_08/target/micros/avr/startup/crt0_init_ram.cpp +++ b/examples/chapter16_08/target/micros/avr/startup/crt0_init_ram.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2022. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter16_08/target/micros/avr/startup/crt1.cpp b/examples/chapter16_08/target/micros/avr/startup/crt1.cpp index c982deaa5..0a3ce7243 100644 --- a/examples/chapter16_08/target/micros/avr/startup/crt1.cpp +++ b/examples/chapter16_08/target/micros/avr/startup/crt1.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2022. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/examples/chapter16_08/target/micros/avr/startup/int_vect.cpp b/examples/chapter16_08/target/micros/avr/startup/int_vect.cpp index 41fa24e67..41b1239d9 100644 --- a/examples/chapter16_08/target/micros/avr/startup/int_vect.cpp +++ b/examples/chapter16_08/target/micros/avr/startup/int_vect.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2022. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/ref_app/src/mcal/avr/mcal_cpu.cpp b/ref_app/src/mcal/avr/mcal_cpu.cpp index a2338eec7..3e58bbf80 100644 --- a/ref_app/src/mcal/avr/mcal_cpu.cpp +++ b/ref_app/src/mcal/avr/mcal_cpu.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // 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) diff --git a/ref_app/src/mcal/avr/mcal_irq.h b/ref_app/src/mcal/avr/mcal_irq.h index 9fa6ff14c..dddc2d89c 100644 --- a/ref_app/src/mcal/avr/mcal_irq.h +++ b/ref_app/src/mcal/avr/mcal_irq.h @@ -12,7 +12,7 @@ { namespace irq { - typedef void config_type; + using config_type = void; auto init(const config_type*) -> void; diff --git a/ref_app/src/mcal/avr/mcal_osc.h b/ref_app/src/mcal/avr/mcal_osc.h index 0b7590878..fb793ab04 100644 --- a/ref_app/src/mcal/avr/mcal_osc.h +++ b/ref_app/src/mcal/avr/mcal_osc.h @@ -5,8 +5,8 @@ // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_OSC_2011_10_20_H_ - #define MCAL_OSC_2011_10_20_H_ +#ifndef MCAL_OSC_2011_10_20_H + #define MCAL_OSC_2011_10_20_H namespace mcal { @@ -18,4 +18,4 @@ } } -#endif // MCAL_OSC_2011_10_20_H_ +#endif // MCAL_OSC_2011_10_20_H diff --git a/ref_app/src/mcal/avr/mcal_port.h b/ref_app/src/mcal/avr/mcal_port.h index 8a1c34905..d5ea3d26a 100644 --- a/ref_app/src/mcal/avr/mcal_port.h +++ b/ref_app/src/mcal/avr/mcal_port.h @@ -8,10 +8,10 @@ #ifndef MCAL_PORT_2012_06_27_H #define MCAL_PORT_2012_06_27_H - #include - #include + #include + auto mcal_port_pin_expander_set_direction_output(const uint8_t bpos) -> void; auto mcal_port_pin_expander_set_direction_input (const uint8_t bpos) -> void; auto mcal_port_pin_expander_set_pin_high (const uint8_t bpos) -> void; diff --git a/ref_app/src/mcal/avr/mcal_reg.h b/ref_app/src/mcal/avr/mcal_reg.h index 21466f49d..2988aacaf 100644 --- a/ref_app/src/mcal/avr/mcal_reg.h +++ b/ref_app/src/mcal/avr/mcal_reg.h @@ -44,6 +44,21 @@ constexpr std::uint8_t ddre { 0x0DU + sfr_offset }; constexpr std::uint8_t porte { 0x0EU + sfr_offset }; + // Timer register values + constexpr std::uint8_t cs10 = 0U; + constexpr std::uint8_t cs11 = 1U; + constexpr std::uint8_t cs12 = 2U; + constexpr std::uint8_t wgm12 = 3U; + constexpr std::uint8_t toie1 = 0U; + constexpr std::uint8_t ocie0a = 1U; + constexpr std::uint8_t ocie0b = 2U; + constexpr std::uint8_t toie0 = 0U; + constexpr std::uint8_t ocie1a = 1U; + constexpr std::uint8_t ocie1b = 2U; + constexpr std::uint8_t toie2 = 0U; + constexpr std::uint8_t ocie2a = 1U; + constexpr std::uint8_t ocie2b = 2U; + // Timer registers constexpr std::uint8_t tifr0 { 0x15U + sfr_offset }; constexpr std::uint8_t tccr0a { 0x24U + sfr_offset };