diff --git a/examples/chapter04_04/chapter04_04.vcxproj b/examples/chapter04_04/chapter04_04.vcxproj
index aca37832a..6e7523a33 100644
--- a/examples/chapter04_04/chapter04_04.vcxproj
+++ b/examples/chapter04_04/chapter04_04.vcxproj
@@ -232,19 +232,11 @@
-
+
true
true
-
- true
- true
-
-
- true
- true
-
-
+
true
true
@@ -335,6 +327,7 @@
+
@@ -351,12 +344,14 @@
+
+
@@ -364,10 +359,18 @@
true
true
+
+ true
+ true
+
true
true
+
+ true
+ true
+
true
true
@@ -386,18 +389,22 @@
+
+
+
+
+
-
@@ -409,7 +416,10 @@
true
true
-
+
+ true
+ true
+
true
true
@@ -422,14 +432,38 @@
true
true
+
+ true
+ true
+
+
+ true
+ true
+
+
+ true
+ true
+
true
true
+
+ true
+ true
+
true
true
+
+ true
+ true
+
+
+ true
+ true
+
true
true
@@ -458,6 +492,10 @@
true
true
+
+ true
+ true
+
true
true
@@ -486,10 +524,22 @@
true
true
+
+ true
+ true
+
true
true
+
+ true
+ true
+
+
+ true
+ true
+
true
true
diff --git a/examples/chapter04_04/chapter04_04.vcxproj.filters b/examples/chapter04_04/chapter04_04.vcxproj.filters
index dc4e995a0..fd076a794 100644
--- a/examples/chapter04_04/chapter04_04.vcxproj.filters
+++ b/examples/chapter04_04/chapter04_04.vcxproj.filters
@@ -87,12 +87,6 @@
src\mcal
-
- src\util\STL\impl\avr
-
-
- src\util\STD_LIBC
-
src\app\led
@@ -165,11 +159,11 @@
src\mcal\host
-
- src\util\STL\impl
+
+ src\util\STD_LIBC
-
- src\util\STL\impl
+
+ src\util\STL\impl\avr
@@ -293,9 +287,6 @@
src\util\utility
-
- src\util\utility
-
src\util\utility
@@ -425,6 +416,36 @@
src\util\STL\impl
+
+ src\util\utility
+
+
+ src\util\utility
+
+
+ src\util\utility
+
+
+ src\util\utility
+
+
+ src\util\utility
+
+
+ src\util\memory
+
+
+ src\util\STL\impl
+
+
+ src\util\STL\impl
+
+
+ src\mcal
+
+
+ src\mcal_pwm
+
@@ -511,5 +532,35 @@
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
+
\ No newline at end of file
diff --git a/examples/chapter04_04/libwinpthread-1.dll b/examples/chapter04_04/libwinpthread-1.dll
deleted file mode 100644
index 39abad74f..000000000
Binary files a/examples/chapter04_04/libwinpthread-1.dll and /dev/null differ
diff --git a/examples/chapter04_04/src/mcal/avr/mcal_pwm_timer1.h b/examples/chapter04_04/src/mcal/avr/mcal_pwm_timer1.h
index ff78a4cdb..36b27cc83 100644
--- a/examples/chapter04_04/src/mcal/avr/mcal_pwm_timer1.h
+++ b/examples/chapter04_04/src/mcal/avr/mcal_pwm_timer1.h
@@ -20,6 +20,7 @@
{
private:
using base_class_type = mcal::pwm::pwm_base;
+ using base_class_type::duty_type;
public:
pwm_timer1() = default;
@@ -97,11 +98,11 @@
{
// Set the duty cycle 0...1000.
- base_class_type::my_duty_cycle = (std::min)(duty_cycle, std::uint16_t(UINT16_C(1000)));
+ base_class_type::set_duty((std::min)(duty_cycle, duty_type(UINT16_C(1000))));
mcal::reg::reg_access_dynamic::reg_set(mcal::reg::ocr1a,
- base_class_type::my_duty_cycle);
+ base_class_type::get_duty());
}
};
diff --git a/examples/chapter04_04/src/mcal/mcal.cpp b/examples/chapter04_04/src/mcal/mcal.cpp
index 3fa1fcdfc..8ea5c9de1 100644
--- a/examples/chapter04_04/src/mcal/mcal.cpp
+++ b/examples/chapter04_04/src/mcal/mcal.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2019.
+// 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)
@@ -23,8 +23,7 @@ void mcal::init()
mcal::ser::init(nullptr);
mcal::spi::init(nullptr);
mcal::pwm::init(nullptr);
+ mcal::eep::init(nullptr);
mcal::cpu::post_init();
-
- mcal::eep::init(nullptr);
}
diff --git a/examples/chapter04_04/src/mcal/mcal.h b/examples/chapter04_04/src/mcal/mcal.h
index 8ae9d30a8..588e01b00 100644
--- a/examples/chapter04_04/src/mcal/mcal.h
+++ b/examples/chapter04_04/src/mcal/mcal.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2019.
+// 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)
diff --git a/examples/chapter04_04/src/mcal/mcal_gcc_cxx_completion.cpp b/examples/chapter04_04/src/mcal/mcal_gcc_cxx_completion.cpp
index 1aaa4b8e8..4b04d32d6 100644
--- a/examples/chapter04_04/src/mcal/mcal_gcc_cxx_completion.cpp
+++ b/examples/chapter04_04/src/mcal/mcal_gcc_cxx_completion.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,13 +10,18 @@
#include
#include
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#endif
+
// Implement std::chrono::high_resolution_clock::now()
// for the standard library's high-resolution clock.
namespace std
{
namespace chrono
{
- high_resolution_clock::time_point high_resolution_clock::now() UTIL_NOEXCEPT
+ high_resolution_clock::time_point high_resolution_clock::now() noexcept
{
// The source of the high-resolution clock is microseconds.
using microsecond_time_point_type =
@@ -37,12 +42,7 @@ namespace std
}
}
-void operator delete(void*) UTIL_NOEXCEPT;
-void operator delete(void*, void*) UTIL_NOEXCEPT;
-
-void* operator new(std::size_t size) UTIL_NOEXCEPT;
-
-void* operator new(std::size_t size) UTIL_NOEXCEPT
+void* operator new(std::size_t size) noexcept
{
// This is a naive and not completely functional
// implementation of operator new(). In particular, there is
@@ -70,10 +70,13 @@ void* operator new(std::size_t size) UTIL_NOEXCEPT
return static_cast(const_cast(p));
}
-void operator delete(void*) UTIL_NOEXCEPT { }
-void operator delete(void*, void*) UTIL_NOEXCEPT { }
+void operator delete(void*) noexcept { }
+#if (defined(__GNUC__) && (__GNUC__ >= 12))
+#else
+void operator delete(void*, void*) noexcept { }
+#endif
#if(__cplusplus >= 201400L)
-void operator delete(void*, std::size_t) UTIL_NOEXCEPT { }
+void operator delete(void*, std::size_t) noexcept { }
#endif
extern "C"
@@ -84,15 +87,13 @@ extern "C"
// Also provide stubbed copies of certain empirically found library functions
// and objects.
- typedef struct struct_unwind_exception_type { unsigned dummy; } _Unwind_Exception;
-
- void abort () UTIL_NOEXCEPT __attribute__((noreturn));
- int atexit (void (*)()) UTIL_NOEXCEPT;
- int at_quick_exit (void (*)()) UTIL_NOEXCEPT;
- void _Exit (int) UTIL_NOEXCEPT __attribute__((noreturn));
- void exit (int) __attribute__((noreturn));
- void quick_exit (int) __attribute__((noreturn));
- int _exit (int);
+ void abort (void) __attribute__((noreturn));
+ int atexit (void (*)(void));
+ int at_quick_exit (void (*)(void));
+ void _Exit (int) __attribute__((noreturn));
+ void exit (int) __attribute__((noreturn));
+ void quick_exit (int) __attribute__((noreturn));
+ void _exit (int) __attribute__((noreturn));
int _isatty (int);
int _lseek (int, int, int);
int _open (const char*, int, int);
@@ -101,21 +102,20 @@ extern "C"
int _write (int, char*, int);
int _fstat (int, void*);
const void* _sbrk (int);
- int _getpid ();
+ int _getpid (void);
int _kill (int, int);
- void __cxa_pure_virtual ();
+ void __cxa_pure_virtual (void);
char* __cxa_demangle (const char*, char*, size_t*, int*);
- void __cxa_call_terminate(_Unwind_Exception*);
// Implementations of patched functions.
- void abort () UTIL_NOEXCEPT { for(;;) { mcal::cpu::nop(); } }
- int atexit (void (*)()) UTIL_NOEXCEPT { return 0; }
- int at_quick_exit (void (*)()) UTIL_NOEXCEPT { return 0; }
- void _Exit (int) UTIL_NOEXCEPT { for(;;) { mcal::cpu::nop(); } }
+ void abort (void) { for(;;) { mcal::cpu::nop(); } }
+ int atexit (void (*)()) { return 0; }
+ int at_quick_exit (void (*)()) { return 0; }
+ void _Exit (int) { for(;;) { mcal::cpu::nop(); } }
void exit (int) { for(;;) { mcal::cpu::nop(); } }
void quick_exit (int) { _Exit(0); }
- int _exit (int) { return -1; }
+ void _exit (int) { for(;;) { mcal::cpu::nop(); } }
int _isatty (int) { return 1; }
int _lseek (int, int, int) { return 0; }
int _open (const char*, int, int) { return -1; }
@@ -124,26 +124,34 @@ extern "C"
int _write (int, char*, int) { return 0; }
int _fstat (int, void*) { return 0; }
const void* _sbrk (int) { return nullptr; }
- int _getpid () { return 1; }
+ int _getpid (void) { return 1; }
int _kill (int, int) { return -1; }
- void __cxa_pure_virtual () { }
+ void __cxa_pure_virtual (void) { }
char* __cxa_demangle (const char*, char*, size_t*, int*) { return nullptr; }
- void __cxa_call_terminate(_Unwind_Exception*) { }
+
+ #if defined(environ)
+ #undef environ
+ #endif
// Provide some patched data values.
const char* const __env[1U] = { nullptr };
const char** const environ = { nullptr };
- int __errno = 0;
- std::uint8_t __fdlib_version = UINT8_C(0);
+ #if (defined(__GNUC__) && defined(__v850__))
+ #else
+ extern int* __errno(void);
+ int* __errno(void) { return nullptr; }
+ #endif
+
+ std::uint8_t __fdlib_version;
}
-// Provide some stubs for specific GCC error handling mechanisms.
namespace std
{
- void __throw_length_error(char const*);
- void __throw_logic_error (char const*);
+ [[noreturn]]
+ void __throw_out_of_range_fmt(char const*, ...) { for(;;) { ; } }
}
-void std::__throw_length_error(char const*) { }
-void std::__throw_logic_error (char const*) { }
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
diff --git a/examples/chapter04_04/src/mcal/mcal_helper.h b/examples/chapter04_04/src/mcal/mcal_helper.h
new file mode 100644
index 000000000..135197861
--- /dev/null
+++ b/examples/chapter04_04/src/mcal/mcal_helper.h
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2020 - 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 MCAL_HELPER_2020_05_21_H_
+ #define MCAL_HELPER_2020_05_21_H_
+
+ #include
+ #include
+
+ #include
+ #include
+
+ namespace mcal { namespace helper {
+
+ template
+ typename std::enable_if<(1U < nop_count) && (nop_count <= 12U), void>::type nop_maker()
+ {
+ nop_maker();
+
+ mcal::cpu::nop();
+ }
+
+ template
+ typename std::enable_if<(nop_count == 1U), void>::type nop_maker() { mcal::cpu::nop(); }
+
+ template
+ typename std::enable_if<(nop_count == 0U), void>::type nop_maker() { }
+
+ template
+ typename std::enable_if<(12U < nop_count), void>::type nop_maker()
+ {
+ for(std::uint_fast16_t i = 0U; i < nop_count; ++i)
+ {
+ mcal::cpu::nop();
+ }
+ }
+
+ template
+ void disable_all_interrupts(const bool = has_disable_enable_interrupts,
+ const typename std::enable_if<(has_disable_enable_interrupts == true)>::type* = nullptr) noexcept
+ {
+ mcal::irq::disable_all();
+ }
+
+ template
+ void enable_all_interrupts(const bool = has_disable_enable_interrupts,
+ const typename std::enable_if<(has_disable_enable_interrupts == true)>::type* = nullptr) noexcept
+ {
+ mcal::irq::enable_all();
+ }
+
+ template
+ void disable_all_interrupts(const bool = has_disable_enable_interrupts,
+ const typename std::enable_if<(has_disable_enable_interrupts == false)>::type* = nullptr) noexcept { }
+
+ template
+ void enable_all_interrupts(const bool = has_disable_enable_interrupts,
+ const typename std::enable_if<(has_disable_enable_interrupts == false)>::type* = nullptr) noexcept { }
+
+ } } // namespace mcal::helper
+
+#endif // MCAL_HELPER_2020_05_21_H_
diff --git a/examples/chapter04_04/src/mcal/mcal_reg_access_dynamic.h b/examples/chapter04_04/src/mcal/mcal_reg_access_dynamic.h
index 85cd37341..e23db33d0 100644
--- a/examples/chapter04_04/src/mcal/mcal_reg_access_dynamic.h
+++ b/examples/chapter04_04/src/mcal/mcal_reg_access_dynamic.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2013 - 2019.
+// Copyright Christopher Kormanyos 2013 - 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)
@@ -8,30 +8,53 @@
#ifndef MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_
#define MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_
+ #if defined(__GNUC__) && (__GNUC__ >= 12)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Warray-bounds"
+ #endif
+
namespace mcal
{
namespace reg
{
- template
+ template
struct reg_access_dynamic final
{
- static register_value_type
- reg_get(const register_address_type address) { return *reinterpret_cast(address); }
-
- static void reg_set(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) = value; }
- static void reg_and(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= value; }
- static void reg_or (const register_address_type address, const register_value_type value) { *reinterpret_cast(address) |= value; }
- static void reg_not(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= register_value_type(~value); }
- static void reg_msk(const register_address_type address, const register_value_type value,
- const register_value_type mask_value) { *reinterpret_cast(address) = register_value_type(register_value_type(reg_get(address) & register_value_type(~mask_value)) | register_value_type(value & mask_value)); }
-
- static void bit_set(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) |= static_cast(1UL << value); }
- static void bit_clr(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= static_cast(~static_cast(1UL << value)); }
- static void bit_not(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) ^= static_cast(1UL << value); }
- static bool bit_get(const register_address_type address, const register_value_type value) { return (static_cast(reg_get(address) & static_cast(1UL << value)) != static_cast(0U)); }
+ using register_address_type = RegisterAddressType;
+ using register_value_type = RegisterValueType;
+
+ static auto reg_get(const register_address_type address) -> register_value_type { return *reinterpret_cast(address); }
+ static auto reg_set(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = value; }
+ static auto reg_and(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & value); }
+ static auto reg_or (const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | value); }
+ static auto reg_not(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~value)); }
+
+ static auto reg_msk(const register_address_type address,
+ const register_value_type value,
+ const register_value_type mask_value) -> void
+ {
+ volatile register_value_type* pa = reinterpret_cast(address);
+
+ *pa =
+ static_cast
+ (
+ static_cast(reg_get(address) & static_cast(~mask_value))
+ | value
+ );
+ }
+
+ static auto bit_set(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | static_cast(1UL << value)); }
+ static auto bit_clr(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~static_cast(1UL << value))); }
+ static auto bit_not(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa ^ static_cast(1UL << value)); }
+ static auto bit_get(const register_address_type address, const register_value_type value) -> bool { return (static_cast(reg_get(address) & static_cast(1UL << value)) != static_cast(0U)); }
};
}
}
+ #if defined(__GNUC__) && (__GNUC__ >= 12)
+ // -Warray-bounds
+ #pragma GCC diagnostic pop
+ #endif
+
#endif // MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_
diff --git a/examples/chapter04_04/src/mcal/mcal_reg_access_static.h b/examples/chapter04_04/src/mcal/mcal_reg_access_static.h
index 457ffa60a..13385af2b 100644
--- a/examples/chapter04_04/src/mcal/mcal_reg_access_static.h
+++ b/examples/chapter04_04/src/mcal/mcal_reg_access_static.h
@@ -1,5 +1,5 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2019.
+///////////////////////////////////////////////////////////////////////////////
+// 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,32 +8,53 @@
#ifndef MCAL_REG_ACCESS_STATIC_2010_12_01_H_
#define MCAL_REG_ACCESS_STATIC_2010_12_01_H_
+ #if defined(__GNUC__) && (__GNUC__ >= 12)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Warray-bounds"
+ #endif
+
namespace mcal
{
namespace reg
{
- template(0)>
+ template(0U)>
struct reg_access_static final
{
- static void reg_set() { *reinterpret_cast(address) = value; }
- static void reg_and() { *reinterpret_cast(address) &= value; }
- static void reg_or () { *reinterpret_cast(address) |= value; }
- static void reg_not() { *reinterpret_cast(address) &= register_value_type(~value); }
- static register_value_type
- reg_get() { return *reinterpret_cast(address); }
+ using register_value_type = RegisterValueType;
+ using register_address_type = RegisterAddressType;
+
+ static auto reg_get() -> register_value_type { volatile register_value_type* pa = reinterpret_cast(address); return *pa; }
+ static auto reg_set() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = value; }
+ static auto reg_and() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & value); }
+ static auto reg_or () -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | value); }
+ static auto reg_not() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~value)); }
template
- static void reg_msk() { *reinterpret_cast(address) = register_value_type(register_value_type(reg_get() & register_value_type(~mask_value)) | register_value_type(value & mask_value)); }
+ static auto reg_msk() -> void
+ {
+ volatile register_value_type* pa = reinterpret_cast(address);
- static void bit_set() { *reinterpret_cast(address) |= static_cast(1ULL << value); }
- static void bit_clr() { *reinterpret_cast(address) &= static_cast(~static_cast(1ULL << value)); }
- static void bit_not() { *reinterpret_cast(address) ^= static_cast(1ULL << value); }
- static bool bit_get() { return (static_cast(reg_get() & static_cast(1ULL << value)) != static_cast(0U)); }
+ *pa =
+ static_cast
+ (
+ static_cast(reg_get() & static_cast(~mask_value))
+ | value
+ );
+ }
+
+ static auto bit_set() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | static_cast(1ULL << value)); }
+ static auto bit_clr() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~static_cast(1ULL << value))); }
+ static auto bit_not() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa ^ static_cast(1ULL << value)); }
+ static auto bit_get() -> bool { return (static_cast(reg_get() & static_cast(1ULL << value)) != static_cast(0U)); }
};
}
}
+ #if defined(__GNUC__) && (__GNUC__ >= 12)
+ #pragma GCC diagnostic pop
+ #endif
+
#endif // MCAL_REG_ACCESS_STATIC_2010_12_01_H_
diff --git a/examples/chapter04_04/src/mcal_led/mcal_led_base.h b/examples/chapter04_04/src/mcal_led/mcal_led_base.h
index 8b2f00511..e9d099b72 100644
--- a/examples/chapter04_04/src/mcal_led/mcal_led_base.h
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_base.h
@@ -1,5 +1,12 @@
-#ifndef MCAL_LED_BASE_2020_04_32_H_
- #define MCAL_LED_BASE_2020_04_32_H_
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2013 - 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 MCAL_LED_BASE_2020_04_32_H
+ #define MCAL_LED_BASE_2020_04_32_H
#include
@@ -8,15 +15,15 @@
class led_base : private util::noncopyable
{
public:
- virtual void toggle() = 0;
- virtual bool state_is_on() const = 0;
+ virtual auto toggle() -> void = 0;
- virtual ~led_base() = default;
+ 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/chapter04_04/src/mcal_led/mcal_led_boolean_state_base.h b/examples/chapter04_04/src/mcal_led/mcal_led_boolean_state_base.h
new file mode 100644
index 000000000..e74ed23b2
--- /dev/null
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_boolean_state_base.h
@@ -0,0 +1,34 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2020 - 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 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
+ {
+ protected:
+ constexpr led_boolean_state_base() = default;
+
+ auto toggle() -> void override
+ {
+ // Toggle the LED state.
+ is_on = (!is_on);
+ }
+
+ auto state_is_on() const -> bool override { return is_on; }
+
+ private:
+ bool is_on { };
+ };
+
+ } } // namespace mcal::led
+
+#endif // MCAL_LED_BOOLEAN_STATE_BASE_2020_08_07_H
diff --git a/examples/chapter04_04/src/mcal_led/mcal_led_console.h b/examples/chapter04_04/src/mcal_led/mcal_led_console.h
index 134d89b05..92516cd2e 100644
--- a/examples/chapter04_04/src/mcal_led/mcal_led_console.h
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_console.h
@@ -1,42 +1,44 @@
-#ifndef MCAL_LED_CONSOLE_2020_04_23_H_
- #define MCAL_LED_CONSOLE_2020_04_23_H_
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2013 - 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 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_base
+ class led_console final : public mcal::led::led_boolean_state_base
{
public:
- led_console(const std::uint_fast8_t i = 0)
- : index(i),
- is_on(false) { }
-
- virtual ~led_console() = default;
+ explicit constexpr led_console(const std::uint_fast8_t i)
+ : my_index(i) { }
- virtual void toggle()
+ auto toggle() -> void override
{
- // Toggle the LED state.
- is_on = (!is_on);
+ using base_class_type = mcal::led::led_boolean_state_base;
// Print the LED state.
std::cout << "LED"
- << unsigned(index)
+ << static_cast(my_index)
<< " is "
- << (is_on ? "on" : "off")
+ << (base_class_type::state_is_on() ? "on" : "off")
<< std::endl;
+
+ base_class_type::toggle();
}
private:
- const std::uint_fast8_t index;
- bool is_on;
-
- virtual bool state_is_on() const { return is_on; }
+ const std::uint_fast8_t my_index;
};
} } // namespace mcal::led
-#endif // MCAL_LED_CONSOLE_2020_04_23_H_
+#endif // MCAL_LED_CONSOLE_2020_04_23_H
diff --git a/examples/chapter04_04/src/mcal_led/mcal_led_port.h b/examples/chapter04_04/src/mcal_led/mcal_led_port.h
index 61508f995..f0d383ef7 100644
--- a/examples/chapter04_04/src/mcal_led/mcal_led_port.h
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_port.h
@@ -1,44 +1,39 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2020.
+// Copyright Christopher Kormanyos 2013 - 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 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
#include
namespace mcal { namespace led {
template
- class led_port : public mcal::led::led_base
+ class led_port : public mcal::led::led_boolean_state_base
{
public:
- led_port() : is_on(false)
+ led_port()
{
port_type::set_pin_low();
port_type::set_direction_output();
}
- virtual ~led_port() = default;
-
- virtual void toggle()
+ auto toggle() -> void override
{
- // Toggle the LED state.
- is_on = (!is_on);
+ using base_class_type = led_boolean_state_base;
port_type::toggle_pin();
- }
- virtual bool state_is_on() const { return is_on; }
-
- private:
- bool is_on;
+ 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/chapter04_04/src/mcal_led/mcal_led_port_inverted.h b/examples/chapter04_04/src/mcal_led/mcal_led_port_inverted.h
new file mode 100644
index 000000000..847661fad
--- /dev/null
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_port_inverted.h
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2020 - 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 MCAL_LED_PORT_INVERTED_2020_08_02_H
+ #define MCAL_LED_PORT_INVERTED_2020_08_02_H
+
+ #include
+ #include
+
+ namespace mcal { namespace led {
+
+ template
+ class led_port_inverted : public mcal::led::led_boolean_state_base
+ {
+ public:
+ led_port_inverted()
+ {
+ port_type::set_pin_high();
+ port_type::set_direction_output();
+ }
+
+ auto toggle() -> void override
+ {
+ using base_class_type = led_boolean_state_base;
+
+ port_type::toggle_pin();
+
+ base_class_type::toggle();
+ }
+ };
+
+ } // namespace led
+ } // namespace mcal
+
+#endif // MCAL_LED_PORT_INVERTED_2020_08_02_H
diff --git a/examples/chapter04_04/src/mcal_led/mcal_led_pwm.h b/examples/chapter04_04/src/mcal_led/mcal_led_pwm.h
index 2ab392f91..d65c84527 100644
--- a/examples/chapter04_04/src/mcal_led/mcal_led_pwm.h
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_pwm.h
@@ -1,5 +1,12 @@
-#ifndef MCAL_LED_PWM_2020_04_23_H_
- #define MCAL_LED_PWM_2020_04_23_H_
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2013 - 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 MCAL_LED_PWM_2020_04_23_H
+ #define MCAL_LED_PWM_2020_04_23_H
#include
#include
@@ -9,27 +16,30 @@
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;
+ auto state_is_on() const -> bool override { return (my_pwm.get_duty() > static_cast(UINT8_C(0))); }
- 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);
}
- virtual bool state_is_on() const { return (my_pwm.get_duty() > 0U); }
-
private:
mcal::pwm::pwm_base& my_pwm;
};
} } // namespace mcal::led
-#endif // MCAL_LED_PWM_2020_04_23_H_
+#endif // MCAL_LED_PWM_2020_04_23_H
diff --git a/examples/chapter04_04/src/mcal_led/mcal_led_rgb_base.h b/examples/chapter04_04/src/mcal_led/mcal_led_rgb_base.h
new file mode 100644
index 000000000..6277b28b8
--- /dev/null
+++ b/examples/chapter04_04/src/mcal_led/mcal_led_rgb_base.h
@@ -0,0 +1,99 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Christopher Kormanyos 2017 - 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 MCAL_LED_RGB_BASE_2023_07_12_H
+ #define MCAL_LED_RGB_BASE_2023_07_12_H
+
+ #include
+
+ #include
+
+ namespace mcal { namespace led {
+
+ class led_rgb_base : public mcal::led::led_boolean_state_base
+ {
+ public:
+ auto toggle() -> void override
+ {
+ using base_class_type = mcal::led::led_boolean_state_base;
+
+ // Toggle the LED state.
+ (base_class_type::state_is_on() ? my_off() : my_on());
+
+ base_class_type::toggle();
+ }
+
+ auto set_color(const std::uint_fast8_t hue_r,
+ const std::uint_fast8_t hue_g,
+ const std::uint_fast8_t hue_b) -> void
+ {
+ my_hue_r = hue_r;
+ my_hue_g = hue_g;
+ my_hue_b = hue_b;
+
+ this->apply_color();
+ }
+
+ auto set_color(const std::uint32_t color) -> void
+ {
+ set_color
+ (
+ static_cast(color >> static_cast(UINT8_C( 0))),
+ static_cast(color >> static_cast(UINT8_C( 8))),
+ static_cast(color >> static_cast(UINT8_C(16)))
+ );
+ }
+
+ constexpr auto get_color() const noexcept -> std::uint32_t
+ {
+ return
+ static_cast
+ (
+ static_cast(static_cast(my_hue_r) << static_cast(UINT8_C( 0)))
+ | static_cast(static_cast(my_hue_g) << static_cast(UINT8_C( 8)))
+ | static_cast(static_cast(my_hue_b) << static_cast(UINT8_C(16)))
+ );
+ }
+
+ constexpr auto get_hue_r() const noexcept -> std::uint_fast8_t { return my_hue_r; }
+ constexpr auto get_hue_g() const noexcept -> std::uint_fast8_t { return my_hue_g; }
+ constexpr auto get_hue_b() const noexcept -> std::uint_fast8_t { return my_hue_b; }
+
+ protected:
+ constexpr led_rgb_base() = default;
+
+ private:
+ std::uint_fast8_t my_hue_r { };
+ std::uint_fast8_t my_hue_g { };
+ std::uint_fast8_t my_hue_b { };
+
+ virtual void apply_color() = 0;
+
+ auto my_on () -> void
+ {
+ set_color
+ (
+ static_cast(UINT8_C(255)),
+ static_cast(UINT8_C(255)),
+ static_cast(UINT8_C(255))
+ );
+ }
+
+ auto my_off() -> void
+ {
+ set_color
+ (
+ static_cast(UINT8_C(0)),
+ static_cast(UINT8_C(0)),
+ static_cast(UINT8_C(0))
+ );
+ }
+ };
+
+ } } // namespace mcal::led
+
+#endif // MCAL_LED_RGB_BASE_2023_07_12_H
diff --git a/examples/chapter04_04/src/mcal_memory/mcal_memory_progmem_iterator.h b/examples/chapter04_04/src/mcal_memory/mcal_memory_progmem_iterator.h
index 6557477aa..bb5de5a95 100644
--- a/examples/chapter04_04/src/mcal_memory/mcal_memory_progmem_iterator.h
+++ b/examples/chapter04_04/src/mcal_memory/mcal_memory_progmem_iterator.h
@@ -17,12 +17,6 @@
namespace mcal { namespace memory { namespace progmem {
- struct input_iterator_tag { };
- struct output_iterator_tag { };
- struct forward_iterator_tag : public input_iterator_tag { };
- struct bidirectional_iterator_tag : public forward_iterator_tag { };
- struct random_access_iterator_tag : public bidirectional_iterator_tag { };
-
template
struct iterator_traits
{
@@ -67,14 +61,14 @@
typename AddressType,
typename AddressDifferenceType>
class progmem_iterator
- : public mcal::memory::progmem::iterator
{
private:
using base_class_type =
- mcal::memory::progmem::iterator;
@@ -155,7 +149,7 @@
operator-(const progmem_iterator& x,
const progmem_iterator& y) noexcept
{
- return (x.current.ptr - y.current.ptr);
+ return (x.current - y.current);
}
friend inline progmem_iterator
@@ -167,11 +161,11 @@
};
template
- typename mcal::memory::progmem::iterator_traits::difference_type
+ typename iterator_traits::difference_type
distance(input_iterator first, input_iterator last) noexcept
{
using local_difference_type =
- typename mcal::memory::progmem::iterator_traits::difference_type;
+ typename iterator_traits::difference_type;
return local_difference_type(last - first);
}
diff --git a/examples/chapter04_04/src/mcal_memory/mcal_memory_sram_ptr.h b/examples/chapter04_04/src/mcal_memory/mcal_memory_sram_ptr.h
index 33baf27c7..0043c89d4 100644
--- a/examples/chapter04_04/src/mcal_memory/mcal_memory_sram_ptr.h
+++ b/examples/chapter04_04/src/mcal_memory/mcal_memory_sram_ptr.h
@@ -25,7 +25,9 @@
using address_type = AddressType;
public:
- using reference = sram_ref;
+ using reference = sram_ref;
using value_type = typename reference::value_type;
using size_type = typename reference::size_type;
using difference_type = typename reference::difference_type;
diff --git a/examples/chapter04_04/src/mcal_memory/mcal_memroy_sram_iterator.h b/examples/chapter04_04/src/mcal_memory/mcal_memroy_sram_iterator.h
index 787618263..e1aa24ec1 100644
--- a/examples/chapter04_04/src/mcal_memory/mcal_memroy_sram_iterator.h
+++ b/examples/chapter04_04/src/mcal_memory/mcal_memroy_sram_iterator.h
@@ -18,12 +18,6 @@
namespace mcal { namespace memory { namespace sram {
- struct input_iterator_tag { };
- struct output_iterator_tag { };
- struct forward_iterator_tag : public input_iterator_tag { };
- struct bidirectional_iterator_tag : public forward_iterator_tag { };
- struct random_access_iterator_tag : public bidirectional_iterator_tag { };
-
template
struct iterator_traits
{
@@ -68,14 +62,14 @@
typename AddressType,
typename AddressDifferenceType>
class sram_iterator
- : public mcal::memory::sram::iterator
{
private:
using base_class_type =
- mcal::memory::sram::iterator;
@@ -166,7 +160,7 @@
operator-(const sram_iterator& x,
const sram_iterator& y) noexcept
{
- return (x.current.ptr - y.current.ptr);
+ return (x.current - y.current);
}
friend inline sram_iterator
@@ -178,11 +172,11 @@
};
template
- typename mcal::memory::sram::iterator_traits::difference_type
+ typename iterator_traits::difference_type
distance(input_iterator first, input_iterator last) noexcept
{
using local_difference_type =
- typename mcal::memory::sram::iterator_traits::difference_type;
+ typename iterator_traits::difference_type;
return local_difference_type(last - first);
}
diff --git a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_base.h b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_base.h
index 0252db06b..5bae70e7f 100644
--- a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_base.h
+++ b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_base.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_PWM_BASE_2020_04_12_H_
- #define MCAL_PWM_BASE_2020_04_12_H_
+#ifndef MCAL_PWM_BASE_2020_04_12_H
+ #define MCAL_PWM_BASE_2020_04_12_H
#include
@@ -17,21 +17,25 @@
class pwm_base : private util::noncopyable
{
public:
- virtual ~pwm_base() = default;
+ using duty_type = std::uint16_t;
- virtual bool init() noexcept = 0;
+ virtual ~pwm_base() noexcept = default;
- virtual void set_duty(const std::uint16_t duty_cycle) = 0;
+ virtual auto init() noexcept -> bool = 0;
- std::uint16_t get_duty() const noexcept { return my_duty_cycle; }
+ virtual auto set_duty(const duty_type duty_cycle) noexcept -> void { my_duty_cycle = duty_cycle; }
- protected:
- pwm_base() : my_duty_cycle(0U) { }
+ auto get_duty() const noexcept -> duty_type { return my_duty_cycle; }
protected:
- std::uint16_t my_duty_cycle;
+ explicit pwm_base(const duty_type initial_duty = static_cast(UINT8_C(0))) noexcept
+ : my_duty_cycle(initial_duty) { }
+
+ private:
+ duty_type my_duty_cycle { };
};
- } }
+ } // namespace pwm
+ } // namespace mcal
-#endif // MCAL_PWM_BASE_2020_04_12_H_
+#endif // MCAL_PWM_BASE_2020_04_12_H
diff --git a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_console.h b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_console.h
index 61dfb95b0..3d49352d4 100644
--- a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_console.h
+++ b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_console.h
@@ -1,12 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2020.
+// Copyright Christopher Kormanyos 2020 - 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 MCAL_PWM_CONSOLE_2020_04_12_H_
- #define MCAL_PWM_CONSOLE_2020_04_12_H_
+#ifndef MCAL_PWM_CONSOLE_2020_04_12_H
+ #define MCAL_PWM_CONSOLE_2020_04_12_H
#include
#include
@@ -24,13 +24,17 @@
public:
pwm_console() = default;
- virtual bool init() noexcept { return true; }
+ auto init() noexcept -> bool override { return true; }
- virtual void set_duty(const std::uint16_t duty_cycle) noexcept
+ auto set_duty(const std::uint16_t duty_cycle) noexcept -> void override
{
- base_class_type::my_duty_cycle = duty_cycle;
+ base_class_type::set_duty(duty_cycle);
- const float duty_cycle_as_percent = float(duty_cycle) / 10.0F;
+ const auto duty_cycle_as_percent =
+ static_cast
+ (
+ static_cast(base_class_type::get_duty()) / 10.0F
+ );
std::stringstream strm;
@@ -43,7 +47,7 @@
std::cout << strm.str() + (std::string(2U, ' ') + "\r");
}
- virtual ~pwm_console() = default;
+ ~pwm_console() override = default;
};
} }
diff --git a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_dummy.h b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_dummy.h
index 0d022d854..e2d353eea 100644
--- a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_dummy.h
+++ b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_dummy.h
@@ -1,12 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2020.
+// Copyright Christopher Kormanyos 2020 - 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 MCAL_PWM_DUMMY_2020_04_29_H_
- #define MCAL_PWM_DUMMY_2020_04_29_H_
+#ifndef MCAL_PWM_DUMMY_2020_04_29_H
+ #define MCAL_PWM_DUMMY_2020_04_29_H
#include
@@ -20,16 +20,17 @@
public:
pwm_dummy() = default;
- virtual bool init() noexcept { return true; }
+ auto init() noexcept -> bool override { return true; }
- virtual void set_duty(const std::uint16_t duty_cycle) noexcept
+ auto set_duty(const std::uint16_t duty_cycle) noexcept -> void override
{
- base_class_type::my_duty_cycle = duty_cycle;
+ base_class_type::set_duty(duty_cycle);
}
- virtual ~pwm_dummy() = default;
+ ~pwm_dummy() override = default;
};
- } }
+ } // namespace pwm
+ } // namespace mcal
-#endif // MCAL_PWM_DUMMY_2020_04_29_H_
+#endif // MCAL_PWM_DUMMY_2020_04_29_H
diff --git a/examples/chapter04_04/src/mcal_pwm/mcal_pwm_port.h b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_port.h
new file mode 100644
index 000000000..5ce686fec
--- /dev/null
+++ b/examples/chapter04_04/src/mcal_pwm/mcal_pwm_port.h
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_PWM_PORT_2023_08_23_H
+ #define MCAL_PWM_PORT_2023_08_23_H
+
+ #include
+
+ namespace mcal { namespace pwm {
+
+ // A software PWM template for a port-pin having the standard
+ // port interface for ref_app. The default resolution is 100 ticks.
+
+ template(UINT8_C(100))>
+ class pwm_port : public pwm_base
+ {
+ private:
+ using base_class_type = pwm_base;
+ using port_pin_type = PortPinType;
+
+ public:
+ using base_class_type::duty_type;
+
+ explicit pwm_port(const duty_type initial_duty = static_cast(UINT8_C(0)))
+ : base_class_type(initial_duty),
+ my_duty_shadow(initial_duty)
+ {
+ port_pin_type::set_pin_low();
+ port_pin_type::set_direction_output();
+ }
+
+ ~pwm_port() noexcept override = default;
+
+ auto init() noexcept -> bool override
+ {
+ return true;
+ }
+
+ auto set_duty(const duty_type duty_cycle) noexcept -> void override { my_duty_shadow = duty_cycle; }
+
+ static constexpr auto get_resolution() noexcept -> duty_type { return MyResolution; }
+
+ auto service() noexcept -> void
+ {
+ // Increment the cycle counter.
+ ++my_cycle_counter;
+
+ ((my_cycle_counter <= base_class_type::get_duty()) ? port_pin_type::set_pin_high() : port_pin_type::set_pin_low());
+
+ if(my_cycle_counter == get_resolution())
+ {
+ // Latch the duty cycle from the shadow register.
+ // This is done at the end of the running cycle.
+ base_class_type::set_duty(my_duty_shadow);
+
+ // Reset the cycle counter for a new PWM period.
+ my_cycle_counter = static_cast(UINT8_C(0));
+ }
+ }
+
+ private:
+ duty_type my_cycle_counter { };
+ duty_type my_duty_shadow { };
+ };
+
+ } // namespace pwm
+ } // namespace mcal
+
+#endif // MCAL_PWM_PORT_2023_08_23_H
diff --git a/examples/chapter04_04/src/mcal_spi/mcal_spi_software_dummy.h b/examples/chapter04_04/src/mcal_spi/mcal_spi_software_dummy.h
index 334a62264..3aa5699e7 100644
--- a/examples/chapter04_04/src/mcal_spi/mcal_spi_software_dummy.h
+++ b/examples/chapter04_04/src/mcal_spi/mcal_spi_software_dummy.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_SPI_SOFTWARE_DUMMY_2020_04_10_H_
- #define MCAL_SPI_SOFTWARE_DUMMY_2020_04_10_H_
+#ifndef MCAL_SPI_SOFTWARE_DUMMY_2020_04_10_H
+ #define MCAL_SPI_SOFTWARE_DUMMY_2020_04_10_H
#include
@@ -22,9 +22,9 @@
spi_software_dummy() = default;
- virtual ~spi_software_dummy() = default;
+ ~spi_software_dummy() override = default;
- virtual bool send(const std::uint8_t byte_to_send)
+ auto send(const std::uint8_t byte_to_send) noexcept -> bool override
{
static_cast(byte_to_send);
@@ -33,10 +33,10 @@
return true;
}
- virtual void select() { }
- virtual void deselect() { }
+ auto select() -> void override { }
+ auto deselect() -> void override { }
};
} } // namespace mcal::spi
-#endif // MCAL_SPI_SOFTWARE_DUMMY_2020_04_10_H_
+#endif // MCAL_SPI_SOFTWARE_DUMMY_2020_04_10_H
diff --git a/examples/chapter04_04/src/mcal_spi/mcal_spi_software_port_driver.h b/examples/chapter04_04/src/mcal_spi/mcal_spi_software_port_driver.h
index 60b7218ee..a73963bf3 100644
--- a/examples/chapter04_04/src/mcal_spi/mcal_spi_software_port_driver.h
+++ b/examples/chapter04_04/src/mcal_spi/mcal_spi_software_port_driver.h
@@ -99,9 +99,9 @@
port_pin_miso_type::set_direction_input();
}
- virtual ~spi_software_port_driver() = default;
+ ~spi_software_port_driver() override = default;
- virtual bool send(const std::uint8_t byte_to_send)
+ auto send(const std::uint8_t byte_to_send) noexcept -> bool override
{
base_class_type::recv_buffer = 0U;
@@ -131,8 +131,8 @@
return true;
}
- virtual void select() { port_pin_csn__type::set_pin_low(); }
- virtual void deselect() { port_pin_csn__type::set_pin_high(); }
+ auto select() -> void override { port_pin_csn__type::set_pin_low(); }
+ auto deselect() -> void override { port_pin_csn__type::set_pin_high(); }
};
} } // namespace mcal::spi
diff --git a/examples/chapter04_04/src/os/os.cpp b/examples/chapter04_04/src/os/os.cpp
index 5578dc732..9afa6747b 100644
--- a/examples/chapter04_04/src/os/os.cpp
+++ b/examples/chapter04_04/src/os/os.cpp
@@ -1,5 +1,5 @@
-///////////////////////////////////////////////////////////////////////////////
-// 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)
@@ -8,28 +8,29 @@
#include
#include
#include
+
#include
#include
#include
-namespace
+namespace local
{
- typedef std::array task_list_type;
+ using task_list_type = std::array;
- typedef std::uint_fast8_t task_index_type;
+ using task_index_type = std::uint_fast8_t;
// The one (and only one) operating system task list.
- task_list_type os_task_list(OS_TASK_LIST);
+ task_list_type os_task_list(OS_TASK_LIST); // NOLINT(cppcoreguidelines-avoid-non-const-global-variables,cert-err58-cpp)
// The index of the running task.
- task_index_type os_task_index;
-}
+ task_index_type os_task_index; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
+} // namespace local
-void os::start_os()
+OS_NORETURN auto os::start_os() -> void
{
// Initialize each task once (and only once) before the task scheduling begins.
- auto const it_init_func = std::for_each(os_task_list.cbegin(),
- os_task_list.cend(),
+ const auto it_init_func = std::for_each(local::os_task_list.cbegin(),
+ local::os_task_list.cend(),
[](const task_control_block& the_tcb)
{
the_tcb.initialize();
@@ -51,36 +52,38 @@ void os::start_os()
const os::tick_type timepoint_of_ckeck_ready = os::timer_type::get_mark();
- os_task_index = static_cast(0U);
+ local::os_task_index = static_cast(0U);
- const auto it_ready_task =
- std::find_if(os_task_list.begin(),
- os_task_list.end(),
- [&timepoint_of_ckeck_ready](task_control_block& tcb) -> bool
+ const auto it_ready_task = // NOLINT(llvm-qualified-auto,readability-qualified-auto)
+ std::find_if(local::os_task_list.begin(),
+ local::os_task_list.end(),
+ [&timepoint_of_ckeck_ready](task_control_block& tcb) // NOLINT(modernize-use-trailing-return-type)
{
- const bool task_is_ready = tcb.execute(timepoint_of_ckeck_ready);
+ const auto task_is_ready = tcb.execute(timepoint_of_ckeck_ready);
- ++os_task_index;
+ ++local::os_task_index;
return task_is_ready;
});
// If no ready-task was found, then service the idle task.
- if(it_ready_task == os_task_list.end())
+ if(it_ready_task == local::os_task_list.end())
{
OS_IDLE_TASK_FUNC();
}
}
}
-bool os::set_event(const task_id_type task_id, const event_type& event_to_set)
+auto os::set_event(const task_id_type task_id, const event_type& event_to_set) -> bool
{
- if(task_id < task_id_end)
+ bool result_set_is_ok { };
+
+ if(task_id < task_id_type::task_id_end)
{
// Get the iterator of the control block corresponding to
// the task id that has been supplied to this subroutine.
- const auto it_task_id = ( os_task_list.begin()
- + task_list_type::size_type(task_id));
+ const auto it_task_id = ( local::os_task_list.begin() // NOLINT(llvm-qualified-auto,readability-qualified-auto)
+ + static_cast(task_id));
// Set the event of the corresponding task.
mcal::irq::disable_all();
@@ -89,20 +92,18 @@ bool os::set_event(const task_id_type task_id, const event_type& event_to_set)
mcal::irq::enable_all();
- return true;
- }
- else
- {
- return false;
+ result_set_is_ok = true;
}
+
+ return result_set_is_ok;
}
-void os::get_event(event_type& event_to_get)
+auto os::get_event(event_type& event_to_get) -> void
{
// Get the iterator of the control block of the running task.
- const auto it_running_task = (os_task_list.cbegin() + os_task_index);
+ const auto it_running_task = (local::os_task_list.cbegin() + local::os_task_index); // NOLINT(llvm-qualified-auto,readability-qualified-auto)
- if(it_running_task != os_task_list.cend())
+ if(it_running_task != local::os_task_list.cend())
{
// Get the event of the running task.
mcal::irq::disable_all();
@@ -115,23 +116,23 @@ void os::get_event(event_type& event_to_get)
}
else
{
- event_to_get = event_type();
+ event_to_get = event_type { };
}
}
-void os::clear_event(const event_type& event_to_clear)
+auto os::clear_event(const event_type& event_to_clear) -> void
{
// Get the iterator of the control block of the running task.
- const auto it_running_task = (os_task_list.begin() + os_task_index);
+ const auto it_running_task = (local::os_task_list.begin() + local::os_task_index); // NOLINT(llvm-qualified-auto,readability-qualified-auto)
- if(it_running_task != os_task_list.end())
+ if(it_running_task != local::os_task_list.end())
{
- const volatile event_type event_clear_mask(~event_to_clear);
+ volatile const auto event_clear_mask = static_cast(~event_to_clear);
// Clear the event of the running task.
mcal::irq::disable_all();
- it_running_task->my_event &= event_clear_mask;
+ it_running_task->my_event = static_cast(it_running_task->my_event & event_clear_mask);
mcal::irq::enable_all();
}
diff --git a/examples/chapter04_04/src/os/os.h b/examples/chapter04_04/src/os/os.h
index fdd9ef67f..db4113a75 100644
--- a/examples/chapter04_04/src/os/os.h
+++ b/examples/chapter04_04/src/os/os.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2016.
+// 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)
@@ -13,12 +13,18 @@
#include
#include
+ #if defined(_MSC_VER)
+ #define OS_NORETURN
+ #else
+ #define OS_NORETURN [[noreturn]]
+ #endif
+
namespace os
{
- void start_os ();
- bool set_event (const task_id_type task_id, const event_type& event_to_set);
- void get_event (event_type& event_to_get);
- void clear_event(const event_type& event_to_clear);
+ OS_NORETURN auto start_os () -> void;
+ auto set_event (const task_id_type task_id, const event_type& event_to_set) -> bool;
+ auto get_event (event_type& event_to_get) -> void;
+ auto clear_event(const event_type& event_to_clear) -> void;
}
#endif // OS_2011_10_20_H_
diff --git a/examples/chapter04_04/src/os/os_cfg.h b/examples/chapter04_04/src/os/os_cfg.h
index 7a2e140a4..7e8b84950 100644
--- a/examples/chapter04_04/src/os/os_cfg.h
+++ b/examples/chapter04_04/src/os/os_cfg.h
@@ -1,12 +1,12 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2016.
+///////////////////////////////////////////////////////////////////////////////
+// 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 OS_CFG_2011_10_20_H_
- #define OS_CFG_2011_10_20_H_
+#ifndef OS_CFG_2011_10_20_H
+ #define OS_CFG_2011_10_20_H
#include
#include
@@ -15,34 +15,33 @@
#include
// Declare the task initialization and the task function of the idle process.
- namespace sys { namespace idle { void task_init(); void task_func(); } }
+ namespace sys { namespace idle { auto task_init() noexcept -> void; auto task_func() -> void; } }
// Define symbols for the task initialization and the task function of the idle process.
#define OS_IDLE_TASK_INIT() sys::idle::task_init()
#define OS_IDLE_TASK_FUNC() sys::idle::task_func()
// Declare all of the task initializations and the task functions.
- namespace app { namespace led { void task_init(); void task_func(); } }
- namespace app { namespace benchmark { void task_init(); void task_func(); } }
+ namespace app { namespace led { auto task_init() -> void; auto task_func() -> void; } }
+ namespace app { namespace benchmark { auto task_init() -> void; auto task_func() -> void; } }
namespace os
{
// Enumerate the task IDs. Note that the order in this list must
// be identical with the order of the tasks in the task list below.
- typedef enum enum_task_id
+ enum class task_id_type
{
task_id_app_led,
task_id_app_benchmark,
task_id_end
- }
- task_id_type;
+ };
// Configure the operating system types.
- typedef void(*function_type)();
+ using function_type = void(*)();
- typedef util::timer timer_type;
- typedef timer_type::tick_type tick_type;
- typedef std::uint_fast16_t event_type;
+ using timer_type = util::timer;
+ using tick_type = timer_type::tick_type;
+ using event_type = std::uint_fast16_t;
static_assert(std::numeric_limits::digits >= 32,
"The operating system timer_type must be at least 32-bits wide.");
@@ -61,22 +60,22 @@
// 4201, 4409, 4637, 4831, 5039, 5279, 5483, 5693, 5881, 6133, 6337,
// 6571, 6793, 6997, 7237, 7499, 7687, 7919
- #define OS_TASK_COUNT static_cast(os::task_id_end)
-
- #define OS_TASK_LIST \
- { \
- { \
- os::task_control_block(app::led::task_init, \
- app::led::task_func, \
- os::timer_type::microseconds(UINT32_C( 2000)), \
- os::timer_type::microseconds(UINT32_C( 0))), \
- os::task_control_block(app::benchmark::task_init, \
- app::benchmark::task_func, \
- os::timer_type::microseconds(UINT32_C(50000)), \
- os::timer_type::microseconds(UINT32_C( 379))), \
- } \
+ constexpr auto OS_TASK_COUNT = static_cast(os::task_id_type::task_id_end);
+
+ #define OS_TASK_LIST \
+ { \
+ { \
+ os::task_control_block(app::led::task_init, \
+ app::led::task_func, \
+ os::timer_type::microseconds(UINT32_C( 2000)), \
+ os::timer_type::microseconds(UINT32_C( 0))), \
+ os::task_control_block(app::benchmark::task_init, \
+ app::benchmark::task_func, \
+ os::timer_type::microseconds(UINT32_C( 50000)), \
+ os::timer_type::microseconds(UINT32_C( 379))), \
+ } \
}
- static_assert(OS_TASK_COUNT > std::size_t(0U), "the task count must exceed zero");
+ static_assert(OS_TASK_COUNT > static_cast(UINT8_C(0)), "the task count must exceed zero");
-#endif // OS_CFG_2011_10_20_H_
+#endif // OS_CFG_2011_10_20_H
diff --git a/examples/chapter04_04/src/os/os_task_control_block.cpp b/examples/chapter04_04/src/os/os_task_control_block.cpp
index 216068567..c1a030cb6 100644
--- a/examples/chapter04_04/src/os/os_task_control_block.cpp
+++ b/examples/chapter04_04/src/os/os_task_control_block.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2016.
+// 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)
@@ -7,10 +7,10 @@
#include
-bool os::task_control_block::execute(const os::tick_type& timepoint_of_ckeck_ready)
+auto os::task_control_block::execute(const os::tick_type& timepoint_of_ckeck_ready) -> bool
{
// Check for a task event.
- const bool task_does_have_event = (my_event != event_type(0U));
+ const auto task_does_have_event = (my_event != static_cast(UINT8_C(0)));
if(task_does_have_event)
{
@@ -19,7 +19,7 @@ bool os::task_control_block::execute(const os::tick_type& timepoint_of_ckeck_rea
}
// Check for a task timeout.
- const bool task_does_have_timeout = ( (my_cycle != os::tick_type(0U))
+ const bool task_does_have_timeout = ( (my_cycle != static_cast(UINT8_C(0)))
&& my_timer.timeout_of_specific_timepoint(timepoint_of_ckeck_ready));
if(task_does_have_timeout)
diff --git a/examples/chapter04_04/src/os/os_task_control_block.h b/examples/chapter04_04/src/os/os_task_control_block.h
index 89f5530fa..aef76aa61 100644
--- a/examples/chapter04_04/src/os/os_task_control_block.h
+++ b/examples/chapter04_04/src/os/os_task_control_block.h
@@ -1,12 +1,12 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright Christopher Kormanyos 2007 - 2016.
+///////////////////////////////////////////////////////////////////////////////
+// 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 OS_TASK_CONTROL_BLOCK_2013_07_30_H_
- #define OS_TASK_CONTROL_BLOCK_2013_07_30_H_
+#ifndef OS_TASK_CONTROL_BLOCK_2013_07_30_H
+ #define OS_TASK_CONTROL_BLOCK_2013_07_30_H
#include
#include
@@ -21,39 +21,49 @@
task_control_block(const function_type init,
const function_type func,
const tick_type cycle,
- const tick_type offset) : my_init (init),
- my_func (func),
- my_cycle(cycle),
- my_timer(offset),
- my_event() { }
+ const tick_type offset) noexcept
+ : my_init (init),
+ my_func (func),
+ my_cycle(cycle),
+ my_timer(offset) { }
- task_control_block(const task_control_block& other_tcb) : my_init (other_tcb.my_init),
- my_func (other_tcb.my_func),
- my_cycle(other_tcb.my_cycle),
- my_timer(other_tcb.my_timer),
- my_event(other_tcb.my_event) { }
+ task_control_block(const task_control_block& other_tcb) noexcept
+ : my_init (other_tcb.my_init),
+ my_func (other_tcb.my_func),
+ my_cycle(other_tcb.my_cycle),
+ my_timer(other_tcb.my_timer),
+ my_event(other_tcb.my_event) { }
- ~task_control_block() { }
+ task_control_block(task_control_block&& other_tcb) noexcept
+ : my_init (other_tcb.my_init),
+ my_func (other_tcb.my_func),
+ my_cycle(other_tcb.my_cycle),
+ my_timer(other_tcb.my_timer),
+ my_event(other_tcb.my_event) { }
+
+ task_control_block() = delete;
+
+ ~task_control_block() = default;
+
+ auto operator=(const task_control_block&) -> task_control_block& = delete;
+ auto operator=(task_control_block&&) noexcept -> task_control_block& = delete;
private:
const function_type my_init;
const function_type my_func;
const tick_type my_cycle;
timer_type my_timer;
- event_type my_event;
-
- void initialize() const { my_init(); }
+ event_type my_event { };
- bool execute(const tick_type& timepoint_of_ckeck_ready);
+ auto initialize() const -> void { my_init(); }
- task_control_block();
- task_control_block& operator=(const task_control_block&);
+ auto execute(const tick_type& timepoint_of_ckeck_ready) -> bool;
- friend void start_os ();
- friend bool set_event (const task_id_type, const event_type&);
- friend void get_event (event_type&);
- friend void clear_event(const event_type&);
+ friend auto start_os () -> void;
+ friend auto set_event (const task_id_type, const event_type&) -> bool;
+ friend auto get_event (event_type&) -> void;
+ friend auto clear_event(const event_type&) -> void;
};
}
-#endif // OS_TASK_CONTROL_BLOCK_2013_07_30_H_
+#endif // OS_TASK_CONTROL_BLOCK_2013_07_30_H
diff --git a/examples/chapter04_04/src/util/STD_LIBC/memory.c b/examples/chapter04_04/src/util/STD_LIBC/memory.c
new file mode 100644
index 000000000..19eeb68b7
--- /dev/null
+++ b/examples/chapter04_04/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/chapter04_04/src/util/STD_LIBC/memory.cpp b/examples/chapter04_04/src/util/STD_LIBC/memory.cpp
deleted file mode 100644
index 1519647a4..000000000
--- a/examples/chapter04_04/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/chapter04_04/src/util/STL/algorithm b/examples/chapter04_04/src/util/STL/algorithm
index 6d6915226..7ea5e58af 100644
--- a/examples/chapter04_04/src/util/STL/algorithm
+++ b/examples/chapter04_04/src/util/STL/algorithm
@@ -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