124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  Created by Greg Clayton on 3/5/07.
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef __CFUtils_h__
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define __CFUtils_h__
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <CoreFoundation/CoreFoundation.h>
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef __cplusplus
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Templatized CF helper class that can own any CF pointer and will
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// call CFRelease() on any valid pointer it owns unless that pointer is
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// explicitly released using the release() member function.
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertemplate <class T>
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass CFReleaser
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Type names for the avlue
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            typedef T element_type;
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Constructors and destructors
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            CFReleaser(T ptr = NULL) : _ptr(ptr) { }
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            CFReleaser(const CFReleaser& copy) : _ptr(copy.get())
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (get())
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ::CFRetain(get());
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            virtual ~CFReleaser() { reset(); }
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Assignments
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            CFReleaser& operator= (const CFReleaser<T>& copy)
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (copy != *this)
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Replace our owned pointer with the new one
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    reset(copy.get());
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Retain the current pointer that we own
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (get())
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        ::CFRetain(get());
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Get the address of the contained type
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            T *     ptr_address()   { return &_ptr; }
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Access the pointer itself
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const   T       get() const     { return _ptr;  }
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            T       get()           { return _ptr;  }
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Set a new value for the pointer and CFRelease our old
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // value if we had a valid one.
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            void    reset(T ptr = NULL)
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (ptr != _ptr)
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (_ptr != NULL)
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                ::CFRelease(_ptr);
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            _ptr = ptr;
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Release ownership without calling CFRelease
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            T    release() { T tmp = _ptr; _ptr = NULL; return tmp; }
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    element_type _ptr;
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif    // #ifdef __cplusplus
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif    // #ifndef __CFUtils_h__
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
82