text: /*
   *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
   *
   *  Use of this source code is governed by a BSD-style license
   *  that can be found in the LICENSE file in the root of the source
   *  tree. An additional intellectual property rights grant can be found
   *  in the file PATENTS.  All contributing project authors may
   *  be found in the AUTHORS file in the root of the source tree.
   *
   */
  
  #ifndef WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_
  #define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_
  
  #include <CoreFoundation/CoreFoundation.h>
  namespace rtc {
  
  template <typename T>
  class ScopedCFTypeRef {
   public:
    // RETAIN: ScopedCFTypeRef should retain the object when it takes
    // ownership.
    // ASSUME: Assume the object already has already been retained.
    // ScopedCFTypeRef takes over ownership.
    enum class RetainPolicy { RETAIN, ASSUME };
  
    ScopedCFTypeRef() : ptr_(nullptr) {}
    explicit ScopedCFTypeRef(T ptr) : ptr_(ptr) {}
    ScopedCFTypeRef(T ptr, RetainPolicy policy) : ScopedCFTypeRef(ptr) {
      if (ptr_ && policy == RetainPolicy::RETAIN)
        CFRetain(ptr_);
    }
  
    ~ScopedCFTypeRef() {
      if (ptr_) {
        CFRelease(ptr_);
      }
    }
  
    T get() const { return ptr_; }
    T operator->() const { return ptr_; }
    explicit operator bool() const { return ptr_; }
  
    bool operator!() const { return !ptr_; }
  
    ScopedCFTypeRef& operator=(const T& rhs) {
      if (ptr_)
        CFRelease(ptr_);
      ptr_ = rhs;
      return *this;
    }
  
    ScopedCFTypeRef& operator=(const ScopedCFTypeRef<T>& rhs) {
      reset(rhs.get(), RetainPolicy::RETAIN);
      return *this;
    }
  
    // This is intended to take ownership of objects that are
    // created by pass-by-pointer initializers.
    T* InitializeInto() {
      RTC_DCHECK(!ptr_);
      return &ptr_;
    }
  
    void reset(T ptr, RetainPolicy policy = RetainPolicy::ASSUME) {
      if (ptr && policy == RetainPolicy::RETAIN)
        CFRetain(ptr);
      if (ptr_)
        CFRelease(ptr_);
      ptr_ = ptr;
    }
  
    T release() {
      T temp = ptr_;
      ptr_ = nullptr;
      return temp;
    }
  
   private:
    T ptr_;
  };
  
  template <typename T>
  static ScopedCFTypeRef<T> AdoptCF(T cftype) {
    return ScopedCFTypeRef<T>(cftype, RetainPolicy::RETAIN);
  }
  
  template <typename T>
  static ScopedCFTypeRef<T> ScopedCF(T cftype) {
    return ScopedCFTypeRef<T>(cftype);
  }
  
  }  // namespace rtc
  
  #endif  // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_
  