5
\$\begingroup\$

I'm currently working with the LLVM JIT framework. There is some graph I had to implement for internal cost bench-marking. It has cyclic node dependencies, so I have to use std::weak_ptr pointers for nodes' children instead of their std::shared_ptr counterparts. When it came to implementing child iterators for the graph's external interface, I've adapted llvm::iterator_base.

template
<
  typename WrappedIteratorT,
  typename T = typename std::remove_reference < decltype(*(std::declval<WrappedIteratorT>()->lock())) >::type
>
struct weak_pointee_iterator
  : public llvm::iterator_adaptor_base
  <
    weak_pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
    typename std::iterator_traits<WrappedIteratorT>::iterator_category,
    T
  >
{
  using strong_counterpart = decltype(std::declval<WrappedIteratorT>()->lock());

  weak_pointee_iterator() = default;
  template <typename U>
  weak_pointee_iterator(U &&u)
    : weak_pointee_iterator::iterator_adaptor_base(std::forward<U &&>(u))
  {}

  bool tryLock() const
  {
    strongPointer_ = (*this->I).lock();
    return strongPointer_ != nullptr;
  }

  T& operator*() const
  {
    if (tryLock()) {
      return *strongPointer_;
    } else {
      llvm_unreachable("Weak pointer expired");
    }
  }
private:
  mutable strong_counterpart strongPointer_;
};
\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.