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.

  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,
  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");
  mutable strong_counterpart strongPointer_;


Your Answer

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