#include <cstdint>
void interpret(uint32_t);

namespace slide1 {
void handle_data(uint32_t raw) { interpret(raw & 0x3FFF'FFFF); }
}  // namespace slide1

namespace slide2 {
constexpr uint32_t make_mask(int Nbits) { return (1ULL << Nbits) - 1; }
void handle_data(uint32_t raw) { interpret(raw & 0x3FFF'FFFF); }

void demo_misuse() {
    [[maybe_unused]] auto x = make_mask(-1);    // no warning!
    [[maybe_unused]] auto y = make_mask(33);    // no warning!
    [[maybe_unused]] auto z = make_mask(0xFF);  // no warning!
}
}  // namespace slide2

namespace slide3 {
template <int Nbits>
uint32_t mask_of{(1ULL << Nbits) - 1};
void handle_data(uint32_t raw) { interpret(raw & mask_of<30>); }
void demo_misuse() {
    // [[maybe_unused]] auto x = mask_of<-1>;    // narrowing (gcc), or
    // narrowing+shift (clang) (clang compile error)
    //  [[maybe_unused]] auto y = mask_of<33>;    // narrowing, compile error
    //  [[maybe_unused]] auto z =
    //    mask_of<0xFF>;  // narrowing (gcc), or narrowing+shift (clang) compile
    //    error
}
}  // namespace slide3

namespace slide4 {
template <int Nbits>
constexpr uint32_t mask_of{(1ULL << Nbits) - 1};
void handle_data(uint32_t raw) { interpret(raw & mask_of<30>); }
void demo_misuse() {
    //    [[maybe_unused]] auto x = mask_of<-1>;    // narrowing (gcc), or
    // narrowing+shift (clang) (clang compile error)
    //  [[maybe_unused]] auto y = mask_of<33>;    // narrowing, compile error
    // [[maybe_unused]] auto z =
    //   mask_of<0xFF>;  // narrowing (gcc), or narrowing+shift (clang) compile
    //   error
}
}  // namespace slide4

namespace slide5 {
template <int N>
concept is_within_32 = (N >= 0 && N <= 32);

template <int Nbits>
    requires is_within_32<Nbits>
constexpr uint32_t mask_of{(1ULL << Nbits) - 1};
void handle_data(uint32_t raw) { interpret(raw & mask_of<30>); }
void demo_misuse() {
    //  [[maybe_unused]] auto x = mask_of<-1>;    // narrowing (gcc), or
    // narrowing+shift (clang) (clang compile error)
    //  [[maybe_unused]] auto y = mask_of<33>;    // narrowing, compile error
    // [[maybe_unused]] auto z =
    //   mask_of<0xFF>;  // narrowing (gcc), or narrowing+shift (clang) compile
    //   error
}
}  // namespace slide5

