#include <cstddef>
#include <tuple>
#include <utility>
#include <cstdint>
#include <type_traits>
#include <iostream>
//#include "stm32f411xe.h"
#define __forceinline _Pragma("inline=forced")
constexpr std::uint32_t GpioaBaseAddr = 0x602194 ;
constexpr std::uint32_t GpiocBaseAddr = 0x602198 ;
struct PortBase
{
};
template <std::uint32_t addr>
struct Port: PortBase
{
__forceinline inline static void Toggle(const std::uint8_t bit)
{
*reinterpret_cast<std::uint32_t*>(addr) ^= (1 << bit) ;
std::cout << (1 << bit) << std::endl ;
}
};
using PortA = Port<GpioaBaseAddr> ;
using PortC = Port<GpiocBaseAddr> ;
template <typename T, std::uint8_t pinNum,
class = typename std::enable_if_t<std::is_base_of<PortBase, T>::value>>
struct Pin
{
__forceinline inline static void Toggle()
{
T::Toggle(pinNum) ;
}
} ;
using Led1 = Pin<PortA, 5> ;
using Led2 = Pin<PortC, 5> ;
using Led3 = Pin<PortC, 8> ;
class LedsContainer
{
friend int main() ;
public:
__forceinline static inline void ToggleAll()
{
std::apply([](auto... args) { (args.Toggle(), ...); }, records);
}
private:
constexpr static auto records = std::make_tuple (
Pin<PortA, 5>{},
Pin<PortC, 5>{},
Pin<PortC, 8>{},
Pin<PortC, 9>{}
) ;
using tRecordsTuple = decltype(records) ;
} ;
int main()
{
LedsContainer::ToggleAll();
return 0 ;
}