#pragma once

static inline constexpr uint32_t countSetBits(uint32_t value)
{
  uint32_t bits = 0;

  while (value)
  {
    value &= value - 1;
    bits++;
  }
  return bits;
}

template <uint32_t GpioID, uint16_t PM=0xFFFF>
class TSimplePort
{ 
  static_assert(PM>0, "Wrong mask");

  static inline auto base() { return (GPIO_TypeDef*)GpioID; }

public:

  TSimplePort() = default;
   
  static inline void toggle()
  {
    if constexpr (PM == 0xFFFF)
      base()->ODR = ~base()->ODR;
    else
      if constexpr (countSetBits(PM)==1)
        if(base()->ODR & PM) base()->BRR = PM; else base()->BSRR = PM;
      else 
        base()->BSRR = (PM << 16) | (~base()->ODR & PM);
  }
 
};