scoped_resource.hpp

Go to the documentation of this file.
00001 /* $Id: scoped_resource.hpp 53741 2012-04-01 08:23:02Z mordante $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  *  @file
00018  *  scoped_resource: class template, functions, helper policies etc.\ for
00019  *  resource management.
00020  */
00021 
00022 #ifndef SCOPED_RESOURCE_H_INCLUDED
00023 #define SCOPED_RESOURCE_H_INCLUDED
00024 
00025 #include "global.hpp"
00026 #include <cstdio> //for FILE
00027 
00028 namespace util
00029 {
00030 /**
00031 * A class template, scoped_resource, designed to implement
00032 * the Resource Acquisition Is Initialization (RAII) approach
00033 * to resource management.
00034 * scoped_resource is designed to be used when a resource
00035 * is initialized at the beginning or middle of a scope,
00036 * and released at the end of the scope.
00037 * The template argument ReleasePolicy is a functor
00038 * which takes an argument of the type of the resource,
00039 * and releases it.
00040 *
00041 * Usage example, for working with files:
00042 *
00043 * @code
00044 * struct close_file { void operator()(int fd) const {close(fd);} };
00045 * ...
00046 * {
00047 *    const scoped_resource<int,close_file> file(open("file.txt",O_RDONLY));
00048 *    read(file, buf, 1000);
00049 * } // file is automatically closed here
00050 * @endcode
00051 *
00052 * Note that scoped_resource has an explicit constructor,
00053 * and prohibits copy-construction, and thus the initialization syntax.
00054 * The assignment syntax must be used when initializing.
00055 *
00056 * I.e. using scoped_resource<int,close_file> file = open("file.txt",O_RDONLY);
00057 * in the above example is illegal.
00058 *
00059 */
00060 template<typename T,typename ReleasePolicy>
00061 class scoped_resource
00062 {
00063     T resource;
00064 
00065     //prohibited operations
00066     scoped_resource(const scoped_resource&);
00067     scoped_resource& operator=(const scoped_resource&);
00068 public:
00069     typedef T resource_type;
00070     typedef ReleasePolicy release_type;
00071 
00072   /**
00073   * Constructor
00074   *
00075   * @param res  This is the resource to be managed
00076   */
00077     scoped_resource(resource_type res = resource_type())
00078             : resource(res) {}
00079 
00080   /**
00081   * The destructor is the main point in this class.
00082   * It takes care of proper deletion of the resource,
00083   * using the provided release policy.
00084   */
00085     virtual ~scoped_resource()
00086     {
00087         release_type()(resource);
00088     }
00089 
00090   /**
00091   * This operator makes sure you can access and use the scoped_resource
00092   * just like you were using the resource itself.
00093   *
00094   * @return the underlying resource
00095   */
00096     operator resource_type() const { return resource; }
00097 
00098   /**
00099   * This function provides explicit access to the resource.
00100   * Its behaviour is identical to operator resource_type()
00101   *
00102   * @return the underlying resource
00103   */
00104     resource_type get() const { return resource; }
00105 
00106   /**
00107   * This function provides convenient direct access to the -> operator
00108   * if the underlying resource is a pointer.
00109   * Only call this function if resource_type is a pointer type.
00110   */
00111     resource_type operator->() const { return resource; }
00112 
00113     void assign(const resource_type& o) {
00114         release_type()(resource);
00115         resource = o;
00116     }
00117 };
00118 
00119 /**
00120 * A helper policy for scoped_ptr.
00121 * It will call the delete operator on a pointer, and assign the pointer to NULL
00122 */
00123 struct delete_item {
00124     template<typename T>
00125     void operator()(T*& p) const { delete p; p = NULL; }
00126 };
00127 /**
00128 * A helper policy for scoped_array.
00129 * It will call the delete[] operator on a pointer, and assign the pointer to NULL
00130 */
00131 struct delete_array {
00132     template<typename T>
00133     void operator()(T*& p) const { delete [] p; p = NULL; }
00134 };
00135 
00136 /**
00137 * A class which implements an approximation of
00138 * template<typename T>
00139 * typedef scoped_resource<T*,delete_item> scoped_ptr<T>;
00140 *
00141 * It is a convenient synonym for a common usage of @ref scoped_resource.
00142 * See scoped_resource for more details on how this class behaves.
00143 *
00144 * Usage example:
00145 * @code
00146 * {
00147 *    const scoped_ptr<Object> ptr(new Object);
00148 *    ...use ptr as you would a normal Object*...
00149 * } // ptr is automatically deleted here
00150 * @endcode
00151 *
00152 * NOTE: use this class only to manage a single object, *never* an array.
00153 * Use scoped_array to manage arrays.
00154 * This distinction is because you may call delete only
00155 * on objects allocated with new,
00156 * delete[] only on objects allocated with new[].
00157 */
00158 template<typename T>
00159 struct scoped_ptr : public scoped_resource<T*,delete_item>
00160 {
00161     explicit scoped_ptr(T* p) : scoped_resource<T*,delete_item>(p) {}
00162 };
00163 
00164 /**
00165 * This class has identical behaviour to @ref scoped_ptr, except it
00166 * manages heap-allocated arrays instead of heap-allocated single objects
00167 *
00168 * Usage example:
00169 * @code
00170 * {
00171 *    const scoped_array<char> ptr(new char[n]);
00172 *    ...use ptr as you would a normal char*...
00173 * } // ptr is automatically deleted here
00174 * @endcode
00175 *
00176 */
00177 template<typename T>
00178 struct scoped_array : public scoped_resource<T*,delete_array>
00179 {
00180     explicit scoped_array(T* p) : scoped_resource<T*,delete_array>(p) {}
00181 };
00182 
00183 /**
00184  * This class specializes the scoped_resource to implement scoped FILEs.
00185  * Not sure this is the best place to place such an utility, though.
00186  */
00187 struct close_FILE
00188 {
00189     void operator()(std::FILE* f) const { if(f != NULL) { std::fclose(f); } }
00190 };
00191 typedef scoped_resource<std::FILE*,close_FILE> scoped_FILE;
00192 
00193 }
00194 
00195 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:08 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs