LCOV - code coverage report
Current view: directory - gfx/skia/include/core - SkTemplates.h (source / functions) Found Hit Coverage
Test: app.info Lines: 32 0 0.0 %
Date: 2012-06-02 Functions: 35 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #ifndef SkTemplates_DEFINED
      11                 : #define SkTemplates_DEFINED
      12                 : 
      13                 : #include "SkTypes.h"
      14                 : 
      15                 : /** \file SkTemplates.h
      16                 : 
      17                 :     This file contains light-weight template classes for type-safe and exception-safe
      18                 :     resource management.
      19                 : */
      20                 : 
      21                 : /** \class SkAutoTCallVProc
      22                 : 
      23                 :     Call a function when this goes out of scope. The template uses two
      24                 :     parameters, the object, and a function that is to be called in the destructor.
      25                 :     If detach() is called, the object reference is set to null. If the object
      26                 :     reference is null when the destructor is called, we do not call the
      27                 :     function.
      28                 : */
      29                 : template <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable {
      30                 : public:
      31               0 :     SkAutoTCallVProc(T* obj): fObj(obj) {}
      32               0 :     ~SkAutoTCallVProc() { if (fObj) P(fObj); }
      33               0 :     T* detach() { T* obj = fObj; fObj = NULL; return obj; }
      34                 : private:
      35                 :     T* fObj;
      36                 : };
      37                 : 
      38                 : /** \class SkAutoTCallIProc
      39                 : 
      40                 : Call a function when this goes out of scope. The template uses two
      41                 : parameters, the object, and a function that is to be called in the destructor.
      42                 : If detach() is called, the object reference is set to null. If the object
      43                 : reference is null when the destructor is called, we do not call the
      44                 : function.
      45                 : */
      46                 : template <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable {
      47                 : public:
      48               0 :     SkAutoTCallIProc(T* obj): fObj(obj) {}
      49               0 :     ~SkAutoTCallIProc() { if (fObj) P(fObj); }
      50                 :     T* detach() { T* obj = fObj; fObj = NULL; return obj; }
      51                 : private:
      52                 :     T* fObj;
      53                 : };
      54                 : 
      55                 : // See also SkTScopedPtr.
      56                 : template <typename T> class SkAutoTDelete : SkNoncopyable {
      57                 : public:
      58                 :     SkAutoTDelete(T* obj, bool deleteWhenDone = true) : fObj(obj) {
      59                 :         fDeleteWhenDone = deleteWhenDone;
      60                 :     }
      61                 :     ~SkAutoTDelete() { if (fDeleteWhenDone) delete fObj; }
      62                 : 
      63                 :     T*      get() const { return fObj; }
      64                 :     void    free() { delete fObj; fObj = NULL; }
      65                 :     T*      detach() { T* obj = fObj; fObj = NULL; return obj; }
      66                 : 
      67                 : private:
      68                 :     T*  fObj;
      69                 :     bool fDeleteWhenDone;
      70                 : };
      71                 : 
      72                 : template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
      73                 : public:
      74                 :     SkAutoTDeleteArray(T array[]) : fArray(array) {}
      75                 :     ~SkAutoTDeleteArray() { delete[] fArray; }
      76                 : 
      77                 :     T*      get() const { return fArray; }
      78                 :     void    free() { delete[] fArray; fArray = NULL; }
      79                 :     T*      detach() { T* array = fArray; fArray = NULL; return array; }
      80                 : 
      81                 : private:
      82                 :     T*  fArray;
      83                 : };
      84                 : 
      85                 : /** Allocate an array of T elements, and free the array in the destructor
      86                 :  */
      87                 : template <typename T> class SkAutoTArray : SkNoncopyable {
      88                 : public:
      89                 :     /** Allocate count number of T elements
      90                 :      */
      91               0 :     SkAutoTArray(size_t count) {
      92               0 :         fArray = NULL;
      93               0 :         if (count) {
      94               0 :             fArray = new T[count];
      95                 :         }
      96               0 :         SkDEBUGCODE(fCount = count;)
      97               0 :     }
      98                 : 
      99               0 :     ~SkAutoTArray() {
     100               0 :         delete[] fArray;
     101               0 :     }
     102                 : 
     103                 :     /** Return the array of T elements. Will be NULL if count == 0
     104                 :      */
     105               0 :     T* get() const { return fArray; }
     106                 :     
     107                 :     /** Return the nth element in the array
     108                 :      */
     109                 :     T&  operator[](int index) const {
     110                 :         SkASSERT((unsigned)index < fCount);
     111                 :         return fArray[index];
     112                 :     }
     113                 : 
     114                 : private:
     115                 :     T*  fArray;
     116                 :     SkDEBUGCODE(size_t fCount;)
     117                 : };
     118                 : 
     119                 : /** Wraps SkAutoTArray, with room for up to N elements preallocated
     120                 :  */
     121                 : template <size_t N, typename T> class SkAutoSTArray : SkNoncopyable {
     122                 : public:
     123                 :     /** Allocate count number of T elements
     124                 :      */
     125                 :     SkAutoSTArray(size_t count) {
     126                 :         if (count > N) {
     127                 :             fArray = new T[count];
     128                 :         } else if (count) {
     129                 :             fArray = new (fStorage) T[count];
     130                 :         } else {
     131                 :             fArray = NULL;
     132                 :         }
     133                 :         fCount = count;
     134                 :     }
     135                 :     
     136                 :     ~SkAutoSTArray() {
     137                 :         if (fCount > N) {
     138                 :             delete[] fArray;
     139                 :         } else {
     140                 :             T* start = fArray;
     141                 :             T* iter = start + fCount;
     142                 :             while (iter > start) {
     143                 :                 (--iter)->~T();
     144                 :             }
     145                 :         }
     146                 :     }
     147                 :     
     148                 :     /** Return the number of T elements in the array
     149                 :      */
     150                 :     size_t count() const { return fCount; }
     151                 :     
     152                 :     /** Return the array of T elements. Will be NULL if count == 0
     153                 :      */
     154                 :     T* get() const { return fArray; }
     155                 :     
     156                 :     /** Return the nth element in the array
     157                 :      */
     158                 :     T&  operator[](int index) const {
     159                 :         SkASSERT((unsigned)index < fCount);
     160                 :         return fArray[index];
     161                 :     }
     162                 :     
     163                 : private:
     164                 :     size_t  fCount;
     165                 :     T*      fArray;
     166                 :     // since we come right after fArray, fStorage should be properly aligned
     167                 :     char    fStorage[N * sizeof(T)];
     168                 : };
     169                 : 
     170                 : /** Allocate a temp array on the stack/heap.
     171                 :     Does NOT call any constructors/destructors on T (i.e. T must be POD)
     172                 : */
     173                 : template <typename T> class SkAutoTMalloc : SkNoncopyable {
     174                 : public:
     175               0 :     SkAutoTMalloc(size_t count) {
     176               0 :         fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
     177               0 :     }
     178                 : 
     179               0 :     ~SkAutoTMalloc() {
     180               0 :         sk_free(fPtr);
     181               0 :     }
     182                 : 
     183                 :     // doesn't preserve contents
     184                 :     void reset (size_t count) {
     185                 :         sk_free(fPtr);
     186                 :         fPtr = fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
     187                 :     }
     188                 : 
     189               0 :     T* get() const { return fPtr; }
     190                 : 
     191                 :     operator T*() {
     192                 :         return fPtr;
     193                 :     }
     194                 : 
     195                 :     operator const T*() const {
     196                 :         return fPtr;
     197                 :     }
     198                 : 
     199                 :     T& operator[](int index) {
     200                 :         return fPtr[index];
     201                 :     }
     202                 : 
     203                 :     const T& operator[](int index) const {
     204                 :         return fPtr[index];
     205                 :     }
     206                 : 
     207                 : private:
     208                 :     T*  fPtr;
     209                 : };
     210                 : 
     211                 : template <size_t N, typename T> class SK_API SkAutoSTMalloc : SkNoncopyable {
     212                 : public:
     213               0 :     SkAutoSTMalloc(size_t count) {
     214               0 :         if (count <= N) {
     215               0 :             fPtr = fTStorage;
     216                 :         } else {
     217               0 :             fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
     218                 :         }
     219               0 :     }
     220                 : 
     221               0 :     ~SkAutoSTMalloc() {
     222               0 :         if (fPtr != fTStorage) {
     223               0 :             sk_free(fPtr);
     224                 :         }
     225               0 :     }
     226                 : 
     227                 :     // doesn't preserve contents
     228                 :     void reset(size_t count) {
     229                 :         if (fPtr != fTStorage) {
     230                 :             sk_free(fPtr);
     231                 :         }
     232                 :         if (count <= N) {
     233                 :             fPtr = fTStorage;
     234                 :         } else {
     235                 :             fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
     236                 :         }
     237                 :     }
     238                 : 
     239               0 :     T* get() const { return fPtr; }
     240                 : 
     241                 :     operator T*() {
     242                 :         return fPtr;
     243                 :     }
     244                 : 
     245                 :     operator const T*() const {
     246                 :         return fPtr;
     247                 :     }
     248                 : 
     249                 :     T& operator[](int index) {
     250                 :         return fPtr[index];
     251                 :     }
     252                 : 
     253                 :     const T& operator[](int index) const {
     254                 :         return fPtr[index];
     255                 :     }
     256                 : 
     257                 : private:
     258                 :     T*          fPtr;
     259                 :     union {
     260                 :         uint32_t    fStorage32[(N*sizeof(T) + 3) >> 2];
     261                 :         T           fTStorage[1];   // do NOT want to invoke T::T()
     262                 :     };
     263                 : };
     264                 : 
     265                 : /**
     266                 :  * Reserves memory that is aligned on double and pointer boundaries.
     267                 :  * Hopefully this is sufficient for all practical purposes.
     268                 :  */
     269                 : template <size_t N> class SkAlignedSStorage : SkNoncopyable {
     270                 : public:
     271                 :     void* get() { return fData; }
     272                 : private:
     273                 :     union {
     274                 :         void*   fPtr;
     275                 :         double  fDouble;
     276                 :         char    fData[N];
     277                 :     };
     278                 : };
     279                 : 
     280                 : /**
     281                 :  * Reserves memory that is aligned on double and pointer boundaries.
     282                 :  * Hopefully this is sufficient for all practical purposes. Otherwise,
     283                 :  * we have to do some arcane trickery to determine alignment of non-POD
     284                 :  * types. Lifetime of the memory is the lifetime of the object.
     285                 :  */
     286                 : template <int N, typename T> class SkAlignedSTStorage : SkNoncopyable {
     287                 : public:
     288                 :     /**
     289                 :      * Returns void* because this object does not initialize the
     290                 :      * memory. Use placement new for types that require a cons.
     291                 :      */
     292                 :     void* get() { return fStorage.get(); }
     293                 : private:
     294                 :     SkAlignedSStorage<sizeof(T)*N> fStorage;
     295                 : };
     296                 : 
     297                 : #endif
     298                 : 

Generated by: LCOV version 1.7