231 Node& operator=(
const Node&) =
delete;
233 : numIncompletePredecessors_(other.numIncompletePredecessors_.load()),
234 numPredecessors_(other.numPredecessors_),
235 invoke_(other.invoke_),
236 destroy_(other.destroy_),
237 funcBuffer_(other.funcBuffer_),
238 dependents_(std::move(other.dependents_)) {
239 other.funcBuffer_ =
nullptr;
243 destroy_(funcBuffer_);
251 template <
typename... Ns>
253 ((void)std::initializer_list<int>{(dependsOnOneNode(nodes), 0)...});
260 invoke_(funcBuffer_);
261 numIncompletePredecessors_.store(kCompleted, std::memory_order_release);
270 for (
const Node* dependent : dependents_) {
281 for (
Node* dependent : dependents_) {
289 return numPredecessors_;
298 return numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted;
308 if (numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted) {
309 numIncompletePredecessors_.store(0, std::memory_order_relaxed);
321 numIncompletePredecessors_.store(kCompleted, std::memory_order_relaxed);
325 template <class F, class X = std::enable_if_t<!std::is_base_of<Node, F>::value,
void>>
326 Node(F&& f) : numIncompletePredecessors_(0) {
327 using FNoRef =
typename std::remove_reference<F>::type;
329 constexpr size_t kFuncSize =
static_cast<size_t>(detail::nextPow2(
sizeof(FNoRef)));
330 funcBuffer_ = allocSmallBuffer<kFuncSize>();
331 new (funcBuffer_) FNoRef(std::forward<F>(f));
332 invoke_ = ::detail::callFunctor<FNoRef>;
333 destroy_ = ::detail::destroyFunctor<FNoRef>;
336 void dependsOnOneNode(Node& node) {
337 node.dependents_.emplace_back(
this);
341 static constexpr size_t kCompleted = std::numeric_limits<size_t>::max();
342 mutable std::atomic<size_t> numIncompletePredecessors_;
343 size_t numPredecessors_ = 0;
346 using InvokerType = void (*)(
void* ptr);
349 InvokerType destroy_;
352 std::vector<Node*> dependents_;
355 friend class SubgraphT;
356 friend class ::detail::ExecutorBase;
357 template <
typename G>
358 friend void setAllNodesIncomplete(
const G& graph);
370 :
Node(std::move(other)), biPropSet_(std::move(other.biPropSet_)) {}
377 template <
class... Ns>
379 ((void)std::initializer_list<int>{(biPropDependsOnOneNode(nodes), 0)...});
388 return biPropSet_ && biPropSet_ == node.biPropSet_;
392 template <class T, class X = std::enable_if_t<!std::is_base_of<BiPropNode, T>::value,
void>>
394 inline void removeFromBiPropSet() {
395 if (biPropSet_ !=
nullptr) {
396 auto it = std::find(biPropSet_->begin(), biPropSet_->end(),
this);
397 if (it != biPropSet_->end()) {
398 biPropSet_->erase(it);
403 DISPENSO_DLL_ACCESS
void biPropDependsOnOneNode(BiPropNode& node);
405 std::shared_ptr<std::vector<const BiPropNode*>> biPropSet_;
408 friend class SubgraphT;
409 friend class ::detail::ExecutorBase;
423 : graph_(other.graph_),
424 nodes_(std::move(other.nodes_)),
425 allocator_(std::move(other.allocator_)) {}
435 nodes_.push_back(
new (allocator_->alloc()) NodeType(std::forward<T>(f)));
436 return *nodes_.back();
442 return nodes_.size();
449 const N&
node(
size_t index)
const {
450 return *nodes_[index];
458 return *nodes_[index];
467 for (
const N* node : nodes_) {
479 for (N* node : nodes_) {
491 using PoolPtr = std::unique_ptr<NoLockPoolAllocator, DeallocFunc>;
493 static constexpr size_t kNodeSizeP2 = detail::nextPow2(
sizeof(NodeType));
495 explicit SubgraphT(
GraphT<N>* graph) : graph_(graph), nodes_(), allocator_(getAllocator()) {}
497 inline void removeNodeFromBiPropSet(Node* ) {}
498 void removeNodeFromBiPropSet(BiPropNode* node) {
499 node->removeFromBiPropSet();
501 void decrementDependentCounters();
502 size_t markNodesWithPredicessors();
503 void removePredecessorDependencies(
size_t numGraphPredecessors);
507 static PoolPtr getAllocator();
508 static void releaseAllocator(NoLockPoolAllocator* ptr);
511#if defined(_WIN32) && !defined(__MINGW32__)
513#pragma warning(disable : 4251)
515 std::vector<N*> nodes_;
518#if defined(_WIN32) && !defined(__MINGW32__)