6#include <userver/concurrent/striped_counter.hpp> 
    7#include <userver/utils/assert.hpp> 
   13class StripedReadIndicatorLock;
 
   31class StripedReadIndicator 
final {
 
   34  StripedReadIndicator();
 
   36  StripedReadIndicator(StripedReadIndicator&&) = 
delete;
 
   37  StripedReadIndicator& operator=(StripedReadIndicator&&) = 
delete;
 
   38  ~StripedReadIndicator();
 
   53  StripedReadIndicatorLock Lock() 
noexcept;
 
   62  bool IsFree() 
const noexcept;
 
   66  template <
typename StripedReadIndicatorRange>
 
   67  static bool AreAllFree(StripedReadIndicatorRange&& indicators) {
 
   69    std::uintptr_t released = 0;
 
   70    for (
const auto& indicator : indicators) {
 
   71      released += indicator.released_count_.Read();
 
   74    std::uintptr_t acquired = 0;
 
   75    for (
const auto& indicator : indicators) {
 
   76      acquired += indicator.acquired_count_.Read();
 
   80            std::numeric_limits<std::uintptr_t>::max() / 2);
 
   81    return acquired == released;
 
   85  std::uintptr_t GetAcquireCountApprox() 
const noexcept;
 
   88  std::uintptr_t GetReleaseCountApprox() 
const noexcept;
 
   91  std::uintptr_t GetActiveCountApprox() 
const noexcept;
 
   94  friend class StripedReadIndicatorLock;
 
   96  void DoLock() 
noexcept;
 
   97  void DoUnlock() 
noexcept;
 
   99  StripedCounter acquired_count_;
 
  100  StripedCounter released_count_;
 
  104class [[nodiscard]] StripedReadIndicatorLock 
final {
 
  107  StripedReadIndicatorLock() 
noexcept = 
default;
 
  109  StripedReadIndicatorLock(StripedReadIndicatorLock&&) 
noexcept;
 
  110  StripedReadIndicatorLock(
const StripedReadIndicatorLock&) 
noexcept;
 
  111  StripedReadIndicatorLock& operator=(StripedReadIndicatorLock&&) 
noexcept;
 
  112  StripedReadIndicatorLock& operator=(
const StripedReadIndicatorLock&) 
noexcept;
 
  113  ~StripedReadIndicatorLock();
 
  116  explicit StripedReadIndicatorLock(StripedReadIndicator& indicator) 
noexcept;
 
  118  friend class StripedReadIndicator;
 
  120  StripedReadIndicator* indicator_{
nullptr};