34    auto const end = range.end();
 
   35    auto itr = range.begin();
 
   39        throw std::invalid_argument{
"Range [start, end) is empty."};
 
   44    using RangeValue = std::ranges::range_value_t<
decltype(range)>;
 
   45    auto consume_itr = [&itr]() -> 
decltype(
auto)
 
   47        using reference_type = std::ranges::range_reference_t<
decltype(range)>;
 
   48        if constexpr (std::is_reference_v<reference_type>)
 
   50            return std::move(*itr);
 
   58    RangeValue result = consume_itr();
 
   62    std::size_t count = 1;
 
   64    for (; itr != end; ++itr, ++count)
 
   66        std::uniform_int_distribution<size_t> distrib(0, count);
 
   67        if (distrib(gen) == 0)
 
   69            result = consume_itr();
 
 
  103        throw std::invalid_argument{
"Data is empty."};
 
  106    const auto sumOfWeights =
 
  107        std::accumulate(data.begin(), data.end(), 0u,
 
  108                        [](
unsigned sum, 
const WeightedElement<T>& element) { return sum + element.weight; });
 
  110    if (sumOfWeights == 0u)
 
  112        throw std::invalid_argument{
"Sum of weights cannot be zero."};
 
  117    auto currentSum = 0u;
 
  119    for (
const auto& elem : data)
 
  121        currentSum += elem.weight;
 
  123        if (currentSum > targetWeightValue)
 
  129    return data.back().value;