#include <array>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <limits>

bool shift_left(std::uint32_t value, unsigned int amount, std::uint32_t& output) {
    if (amount >= 32U) {
        return false;
    }
    output = value << amount;
    return true;
}

int main() {
    if (std::numeric_limits<unsigned int>::digits != 32 ||
        std::numeric_limits<int>::digits != 31) {
        std::cout << "unsupported-integer-environment\n";
        return 1;
    }
    const std::uint32_t value{258U};
    std::array<std::uint8_t, 4> bytes{};
    for (std::size_t i{0}; i < bytes.size(); ++i) {
        bytes[i] = static_cast<std::uint8_t>((value >> (8U * i)) & 255U);
    }
    std::uint32_t decoded{0U};
    for (std::size_t i{0}; i < bytes.size(); ++i) {
        decoded |= static_cast<std::uint32_t>(bytes[i]) << (8U * i);
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << static_cast<unsigned int>(bytes[i]);
    }
    std::cout << "\ndecoded=" << decoded << '\n';
    const std::uint8_t narrowed{static_cast<std::uint8_t>(258U)};
    std::cout << "narrowed=" << static_cast<unsigned int>(narrowed) << '\n';
    std::uint32_t shifted{9U};
    const bool zero{shift_left(1U, 0U, shifted)};
    std::cout << "shift-0=" << zero << " value=" << shifted << '\n';
    const bool last{shift_left(1U, 31U, shifted)};
    std::cout << "shift-31=" << last << " value=" << shifted << '\n';
    const bool rejected{shift_left(1U, 32U, shifted)};
    std::cout << "shift-32=" << rejected << " retained=" << shifted << '\n';
    const std::uint32_t top{2147483648U};
    const std::uint32_t discarded{top << 1U};
    std::cout << "discarded=" << discarded << '\n';
    if (decoded != value || !zero || !last || rejected ||
        shifted != top || discarded != 0U || narrowed != 2U) {
        return 1;
    }
    return 0;
}
