init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
267
Telegram/ThirdParty/range-v3/include/range/v3/view/sample.hpp
vendored
Normal file
267
Telegram/ThirdParty/range-v3/include/range/v3/view/sample.hpp
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Casey Carter 2016
|
||||
//
|
||||
// Use, modification and distribution is subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Project home: https://github.com/ericniebler/range-v3
|
||||
//
|
||||
|
||||
#ifndef RANGES_V3_VIEW_SAMPLE_HPP
|
||||
#define RANGES_V3_VIEW_SAMPLE_HPP
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/algorithm/shuffle.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng,
|
||||
bool = (bool)sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>>
|
||||
class size_tracker
|
||||
{
|
||||
range_difference_t<Rng> size_;
|
||||
|
||||
public:
|
||||
CPP_assert(forward_range<Rng> || sized_range<Rng>);
|
||||
size_tracker() = default;
|
||||
size_tracker(Rng & rng)
|
||||
: size_(ranges::distance(rng))
|
||||
{}
|
||||
void decrement()
|
||||
{
|
||||
--size_;
|
||||
}
|
||||
range_difference_t<Rng> get(Rng &, iterator_t<Rng> &) const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
};
|
||||
|
||||
// Impl for sized_sentinel_for (no need to store anything)
|
||||
template<typename Rng>
|
||||
class size_tracker<Rng, true>
|
||||
{
|
||||
public:
|
||||
size_tracker() = default;
|
||||
size_tracker(Rng &)
|
||||
{}
|
||||
void decrement()
|
||||
{}
|
||||
range_difference_t<Rng> get(Rng & rng, iterator_t<Rng> const & it) const
|
||||
{
|
||||
return ranges::end(rng) - it;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// Take a random sampling from another view
|
||||
template<typename Rng, typename URNG>
|
||||
class sample_view : public view_facade<sample_view<Rng, URNG>, finite>
|
||||
{
|
||||
friend range_access;
|
||||
using D = range_difference_t<Rng>;
|
||||
Rng rng_;
|
||||
// Mutable is OK here because sample_view is an Input view.
|
||||
mutable range_difference_t<Rng> size_;
|
||||
URNG * engine_;
|
||||
|
||||
template<bool IsConst>
|
||||
class cursor
|
||||
{
|
||||
friend cursor<!IsConst>;
|
||||
|
||||
using Base = meta::const_if_c<IsConst, Rng>;
|
||||
meta::const_if_c<IsConst, sample_view> * parent_;
|
||||
iterator_t<Base> current_;
|
||||
RANGES_NO_UNIQUE_ADDRESS detail::size_tracker<Base> size_;
|
||||
|
||||
D pop_size()
|
||||
{
|
||||
return size_.get(parent_->rng_, current_);
|
||||
}
|
||||
void advance()
|
||||
{
|
||||
if(parent_->size_ > 0)
|
||||
{
|
||||
using Dist = std::uniform_int_distribution<D>;
|
||||
Dist dist{};
|
||||
URNG & engine = *parent_->engine_;
|
||||
|
||||
for(;; ++current_, size_.decrement())
|
||||
{
|
||||
RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
|
||||
auto n = pop_size();
|
||||
RANGES_EXPECT(n > 0);
|
||||
typename Dist::param_type const interval{0, n - 1};
|
||||
if(dist(engine, interval) < parent_->size_)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = range_value_t<Rng>;
|
||||
using difference_type = D;
|
||||
|
||||
cursor() = default;
|
||||
explicit cursor(meta::const_if_c<IsConst, sample_view> * rng)
|
||||
: parent_(rng)
|
||||
, current_(ranges::begin(rng->rng_))
|
||||
, size_{rng->rng_}
|
||||
{
|
||||
auto n = pop_size();
|
||||
if(rng->size_ > n)
|
||||
rng->size_ = n;
|
||||
advance();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: parent_(that.parent_)
|
||||
, current_(std::move(that.current_))
|
||||
, size_(that.size_)
|
||||
{}
|
||||
range_reference_t<Rng> read() const
|
||||
{
|
||||
return *current_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
RANGES_EXPECT(parent_);
|
||||
return parent_->size_ <= 0;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(parent_);
|
||||
RANGES_EXPECT(parent_->size_ > 0);
|
||||
--parent_->size_;
|
||||
RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
|
||||
++current_;
|
||||
size_.decrement();
|
||||
advance();
|
||||
}
|
||||
};
|
||||
|
||||
cursor<false> begin_cursor()
|
||||
{
|
||||
return cursor<false>{this};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND
|
||||
(sized_range<meta::const_if_c<Const, Rng>> ||
|
||||
sized_sentinel_for<sentinel_t<meta::const_if_c<Const, Rng>>,
|
||||
iterator_t<meta::const_if_c<Const, Rng>>> ||
|
||||
forward_range<meta::const_if_c<Const, Rng>>)) //
|
||||
cursor<Const> begin_cursor() const
|
||||
{
|
||||
return cursor<true>{this};
|
||||
}
|
||||
|
||||
public:
|
||||
sample_view() = default;
|
||||
|
||||
explicit sample_view(Rng rng, D sample_size, URNG & generator)
|
||||
: rng_(std::move(rng))
|
||||
, size_(sample_size)
|
||||
, engine_(std::addressof(generator))
|
||||
{
|
||||
RANGES_EXPECT(sample_size >= 0);
|
||||
}
|
||||
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng, typename URNG>
|
||||
sample_view(Rng &&, range_difference_t<Rng>, URNG &)
|
||||
->sample_view<views::all_t<Rng>, URNG>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// Returns a random sample of a range of length `size(range)`.
|
||||
struct sample_base_fn
|
||||
{
|
||||
template(typename Rng, typename URNG = detail::default_random_engine)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
uniform_random_bit_generator<URNG> AND
|
||||
convertible_to<invoke_result_t<URNG &>, range_difference_t<Rng>> AND
|
||||
(sized_range<Rng> ||
|
||||
sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>> ||
|
||||
forward_range<Rng>)) //
|
||||
sample_view<all_t<Rng>, URNG> operator()(
|
||||
Rng && rng,
|
||||
range_difference_t<Rng> sample_size,
|
||||
URNG & generator = detail::get_random_engine()) const
|
||||
{
|
||||
return sample_view<all_t<Rng>, URNG>{
|
||||
all(static_cast<Rng &&>(rng)), sample_size, generator};
|
||||
}
|
||||
|
||||
/// \cond
|
||||
template<typename Rng, typename URNG>
|
||||
invoke_result_t<sample_base_fn, Rng, range_difference_t<Rng>, URNG &> //
|
||||
operator()(
|
||||
Rng && rng,
|
||||
range_difference_t<Rng> sample_size,
|
||||
detail::reference_wrapper_<URNG> r) const
|
||||
{
|
||||
return (*this)(static_cast<Rng &&>(rng), sample_size, r.get());
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
struct sample_fn : sample_base_fn
|
||||
{
|
||||
using sample_base_fn::operator();
|
||||
|
||||
template(typename Size, typename URNG = detail::default_random_engine)(
|
||||
requires integral<Size> AND uniform_random_bit_generator<URNG>)
|
||||
constexpr auto operator()(
|
||||
Size n,
|
||||
URNG & urng = detail::get_random_engine()) const //
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
sample_base_fn{}, n, detail::reference_wrapper_<URNG>(urng)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates sample_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(sample_fn, sample)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::sample_view)
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user