#pragma once
#include <cstdint>
#include <limits>

namespace
{
inline std::uint64_t splitmix64(std::uint64_t x)
{
    x += 0x9e3779b97f4a7c15ULL;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
    return x ^ (x >> 31);
}

inline int makeSeedForBatch(int baseSeed, std::size_t batchId)
{
    std::uint64_t x =
        static_cast<std::uint64_t>(
            static_cast<std::uint32_t>(baseSeed)
        );

    x ^= splitmix64(batchId + 0x9e3779b97f4a7c15ULL);

    const std::uint64_t mixed = splitmix64(x);

    return static_cast<int>(
               mixed %
               static_cast<std::uint64_t>(
                   std::numeric_limits<int>::max() - 1
               )
           ) + 1;
}
}
