Program Listing for File Inlet.hpp¶
↰ Return to documentation for file (include/uit/spouts/Inlet.hpp)
#pragma once
#ifndef UIT_SPOUTS_INLET_HPP_INCLUDE
#define UIT_SPOUTS_INLET_HPP_INCLUDE
#include <atomic>
#include <cstdint>
#include <iostream>
#include <memory>
#include <stddef.h>
#include <utility>
#include "../../uitsl/debug/occupancy_audit.hpp"
#include "../../uitsl/nonce/CircularIndex.hpp"
#include "../../uitsl/utility/print_utils.hpp"
#include "../ducts/Duct.hpp"
namespace uit {
template<typename ImplSpec_>
class Inlet {
public:
using ImplSpec = ImplSpec_;
private:
using T = typename ImplSpec::T;
constexpr inline static size_t N{ ImplSpec::N };
using index_t = uitsl::CircularIndex<N>;
using duct_t = internal::Duct<ImplSpec>;
std::shared_ptr<duct_t> duct;
size_t successful_put_count{};
size_t blocked_put_count{};
// How many TryPut calls have dropped?
size_t dropped_put_count{};
uitsl_occupancy_auditor;
bool DoTryPut(const T& val) { return duct->TryPut(val); }
template<typename P>
bool DoTryPut(P&& val) { return duct->TryPut(std::forward<P>(val)); }
public:
Inlet(
std::shared_ptr<duct_t> duct_
) : duct(duct_) { ; }
// potentially blocking
void Put(const T& val) {
uitsl_occupancy_audit(1);
bool was_blocked{ false };
while (!DoTryPut(val)) was_blocked = true;
blocked_put_count += was_blocked;
}
// non-blocking
bool TryPut(const T& val) {
uitsl_occupancy_audit(1);
if ( DoTryPut(val) ) return true;
else { ++dropped_put_count; return false; }
}
// non-blocking
template<typename P>
bool TryPut(P&& val) {
uitsl_occupancy_audit(1);
if ( DoTryPut(std::forward<P>(val)) ) return true;
else { ++dropped_put_count; return false; }
}
bool TryFlush() { return duct->TryFlush(); }
void Flush() { while( !TryFlush() ); }
size_t GetSuccessfulPutCount() const { return successful_put_count; }
size_t GetBlockedPutCount() const { return blocked_put_count; }
size_t GetDroppedPutCount() const { return dropped_put_count; }
template <typename WhichDuct, typename... Args>
void EmplaceDuct(Args&&... args) {
duct->template EmplaceImpl<WhichDuct>(std::forward<Args>(args)...);
}
template <typename WhichDuct, typename... Args>
void SplitDuct(Args&&... args) {
duct = std::make_shared<duct_t>(
std::in_place_type_t<WhichDuct>{},
std::forward<Args>(args)...
);
}
typename duct_t::uid_t GetDuctUID() const { return duct->GetUID(); }
emp::optional<bool> HoldsIntraImpl() const { return duct->HoldsIntraImpl(); }
emp::optional<bool> HoldsThreadImpl() const {
return duct->HoldsThreadImpl();
}
emp::optional<bool> HoldsProcImpl() const { return duct->HoldsProcImpl(); }
std::string ToString() const {
std::stringstream ss;
ss << uitsl::format_member("duct_t duct", *duct) << std::endl;
ss << uitsl::format_member(
"size_t successful_put_count",
successful_put_count
) << std::endl;
ss << uitsl::format_member(
"size_t dropped_put_count",
dropped_put_count
) << std::endl;
ss << uitsl::format_member(
"size_t blocked_put_count",
blocked_put_count
);
return ss.str();
}
};
} // namespace uit
#endif // #ifndef UIT_SPOUTS_INLET_HPP_INCLUDE