225 Node& operator=(
const Node&) =
delete;
227 : numIncompletePredecessors_(other.numIncompletePredecessors_.load()),
228 numPredecessors_(other.numPredecessors_),
229 invoke_(other.invoke_),
230 destroy_(other.destroy_),
231 funcBuffer_(other.funcBuffer_),
232 dependents_(std::move(other.dependents_)) {
233 other.funcBuffer_ =
nullptr;
237 destroy_(funcBuffer_);
245 template <
typename... Ns>
247 ((void)std::initializer_list<int>{(dependsOnOneNode(nodes), 0)...});
254 invoke_(funcBuffer_);
255 numIncompletePredecessors_.store(kCompleted, std::memory_order_release);
264 for (
const Node* dependent : dependents_) {
275 for (
Node* dependent : dependents_) {
283 return numPredecessors_;
292 return numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted;
302 if (numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted) {
303 numIncompletePredecessors_.store(0, std::memory_order_relaxed);
315 numIncompletePredecessors_.store(kCompleted, std::memory_order_relaxed);
319 template <class F, class X = std::enable_if_t<!std::is_base_of<Node, F>::value,
void>>
320 Node(F&& f) : numIncompletePredecessors_(0) {
321 using FNoRef =
typename std::remove_reference<F>::type;
323 constexpr size_t kFuncSize =
static_cast<size_t>(detail::nextPow2(
sizeof(FNoRef)));
324 funcBuffer_ = allocSmallBuffer<kFuncSize>();
325 new (funcBuffer_) FNoRef(std::forward<F>(f));
326 invoke_ = ::detail::callFunctor<FNoRef>;
327 destroy_ = ::detail::destroyFunctor<FNoRef>;
330 void dependsOnOneNode(Node& node) {
331 node.dependents_.emplace_back(
this);
335 static constexpr size_t kCompleted = std::numeric_limits<size_t>::max();
336 mutable std::atomic<size_t> numIncompletePredecessors_;
337 size_t numPredecessors_ = 0;
340 using InvokerType = void (*)(
void* ptr);
343 InvokerType destroy_;
346 std::vector<Node*> dependents_;
349 friend class SubgraphT;
350 friend class ::detail::ExecutorBase;
351 template <
typename G>
352 friend void setAllNodesIncomplete(
const G& graph);
364 :
Node(std::move(other)), biPropSet_(std::move(other.biPropSet_)) {}
371 template <
class... Ns>
373 ((void)std::initializer_list<int>{(biPropDependsOnOneNode(nodes), 0)...});
382 return biPropSet_ && biPropSet_ == node.biPropSet_;
386 template <class T, class X = std::enable_if_t<!std::is_base_of<BiPropNode, T>::value,
void>>
388 inline void removeFromBiPropSet() {
389 if (biPropSet_ !=
nullptr) {
390 auto it = std::find(biPropSet_->begin(), biPropSet_->end(),
this);
391 if (it != biPropSet_->end()) {
392 biPropSet_->erase(it);
397 DISPENSO_DLL_ACCESS
void biPropDependsOnOneNode(BiPropNode& node);
399 std::shared_ptr<std::vector<const BiPropNode*>> biPropSet_;
402 friend class SubgraphT;
403 friend class ::detail::ExecutorBase;
417 : graph_(other.graph_),
418 nodes_(std::move(other.nodes_)),
419 allocator_(std::move(other.allocator_)) {}
429 nodes_.push_back(
new (allocator_->alloc()) NodeType(std::forward<T>(f)));
430 return *nodes_.back();
436 return nodes_.size();
443 const N&
node(
size_t index)
const {
444 return *nodes_[index];
452 return *nodes_[index];
461 for (
const N* node : nodes_) {
473 for (N* node : nodes_) {
485 using PoolPtr = std::unique_ptr<NoLockPoolAllocator, DeallocFunc>;
487 static constexpr size_t kNodeSizeP2 = detail::nextPow2(
sizeof(NodeType));
489 explicit SubgraphT(
GraphT<N>* graph) : graph_(graph), nodes_(), allocator_(getAllocator()) {}
491 inline void removeNodeFromBiPropSet(Node* ) {}
492 void removeNodeFromBiPropSet(BiPropNode* node) {
493 node->removeFromBiPropSet();
495 void decrementDependentCounters();
496 size_t markNodesWithPredicessors();
497 void removePredecessorDependencies(
size_t numGraphPredecessors);
501 static PoolPtr getAllocator();
502 static void releaseAllocator(NoLockPoolAllocator* ptr);
505#if defined(_WIN32) && !defined(__MINGW32__)
507#pragma warning(disable : 4251)
509 std::vector<N*> nodes_;
512#if defined(_WIN32) && !defined(__MINGW32__)