Chromium Base - Unretained, RetainedRef, Owned, Passed, IgnoreResult

Unretained是对internal::UnretainedWrapper进行的封装。

static inline internal::UnretainedWrapper<T> Unretained(T* o) {
  return internal::UnretainedWrapper<T>(o);
}

UnretainedWrapper其实很简单,就只实现了一个get()操作,把传入的指针存在类里面而已:

template <typename T>
class UnretainedWrapper {
 public:
  explicit UnretainedWrapper(T* o) : ptr_(o) {}
  T* get() const { return ptr_; }
 private:
  T* ptr_;
};

--------------------------------------------------------------------------------------------------------------------------------

RetainedRef则相对复杂一些,它是internal::RetainedRefWrapper的封装。

template <typename T>
static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) {
  return internal::RetainedRefWrapper<T>(o);
}
template <typename T>
static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) {
  return internal::RetainedRefWrapper<T>(std::move(o));
}

观察RetainedRefWrapper的定义,可以发现它用scoped_refptrhttp://chromium.world/?id=8)把指针包裹起来。在RetainedRefWrapper构造的时候,scoped_refptr也会被构造,从而给ptr加上1次引用计数。同理,在销毁时,ptr的引用计数也会减少1。

template <typename T>
class RetainedRefWrapper {
 public:
  explicit RetainedRefWrapper(T* o) : ptr_(o) {}
  explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
  T* get() const { return ptr_.get(); }
 private:
  scoped_refptr<T> ptr_;
};

--------------------------------------------------------------------------------------------------------------------------------

再来是Owned。它是OwnedWrapper的封装。

template <typename T>
static inline internal::OwnedWrapper<T> Owned(T* o) {
  return internal::OwnedWrapper<T>(o);
}
template <typename T>
static inline internal::OwnedWrapper<T> Owned(std::unique_ptr<T>&& ptr) {
  return internal::OwnedWrapper<T>(std::move(ptr));
}

不难理解,它是对于unique_ptr的二次封装,在构造时,将指针转移给unique_ptr<T> ptr,后续则由unique_ptr管理,从而实现“占有”的语义。

template <typename T>
class OwnedWrapper {
 public:
  explicit OwnedWrapper(T* o) : ptr_(o) {}
  explicit OwnedWrapper(std::unique_ptr<T>&& ptr) : ptr_(std::move(ptr)) {}
  T* get() const { return ptr_.get(); }
 private:
  std::unique_ptr<T> ptr_;
};

本文由@leonwxqian (各社交媒体同号)编写。


Passed,与前面类似,是PassedWrapper的封装。

template <typename T,
          std::enable_if_t<!std::is_lvalue_reference<T>::value>* = nullptr>
static inline internal::PassedWrapper<T> Passed(T&& scoper) {
  return internal::PassedWrapper<T>(std::move(scoper));
}
template <typename T>
static inline internal::PassedWrapper<T> Passed(T* scoper) {
  return internal::PassedWrapper<T>(std::move(*scoper));
}

它的实现稍微复杂一些,Passed是一个用于忽略const的scoper的、可以复制的适配器。它实现了Take()语义,猜测是用于unique_ptr之类的指针管理类,Take以后的内容在它的scoper_中存活。

template <typename T>
class PassedWrapper {
 public:
  explicit PassedWrapper(T&& scoper) : is_valid_(true), scoper_(std::move(scoper)) {}
  PassedWrapper(PassedWrapper&& other) : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
  T Take() const {
    CHECK(is_valid_);
    is_valid_ = false;
    return std::move(scoper_);
  }
 private:
  mutable bool is_valid_;
  mutable T scoper_;
};

--------------------------------------------------------------------------------------------------------------------------------

IgnoreResult,是IgnoreResultHelper的封装。

template <typename T>
static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
  return internal::IgnoreResultHelper<T>(std::move(data));
}

可以看到它只是简单地保存了仿函数functor_。

template <typename T>
struct IgnoreResultHelper {
  explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {}
  explicit operator bool() const { return !!functor_; }
  T functor_;
};

再下面一些还定义了这个仿函数的语义,即通过这个类构造一个可以忽略返回结果的仿函数并提供执行(Invoke)语义。

// For IgnoreResults.
template <typename T>
struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
  using RunType =
      typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType;
  template <typename IgnoreResultType, typename... RunArgs>
  static void Invoke(IgnoreResultType&& ignore_result_helper,
                     RunArgs&&... args) {
    FunctorTraits<T>::Invoke(
        std::forward<IgnoreResultType>(ignore_result_helper).functor_,
        std::forward<RunArgs>(args)...);
  }
};