180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2010 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrTemplates_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrTemplates_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrNoncopyable.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Use to cast a ptr to a different type, and maintain strict-aliasing
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Dst, typename Src> Dst GrTCast(Src src) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    union {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Src src;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Dst dst;
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } data;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    data.src = src;
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return data.dst;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * takes a T*, saves the value it points to,  in and restores the value in the
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * destructor
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * e.g.:
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * {
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *      GrAutoTRestore<int*> autoCountRestore;
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *      if (useExtra) {
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *          autoCountRestore.reset(&fCount);
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *          fCount += fExtraCount;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *      }
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *      ...
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * }  // fCount is restored
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename T> class GrAutoTRestore : public GrNoncopyable {
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAutoTRestore() : fPtr(NULL), fVal() {}
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAutoTRestore(T* ptr) {
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPtr = ptr;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL != ptr) {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fVal = *ptr;
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~GrAutoTRestore() {
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL != fPtr) {
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *fPtr = fVal;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // restores previously saved value (if any) and saves value for passed T*
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset(T* ptr) {
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL != fPtr) {
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *fPtr = fVal;
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPtr = ptr;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fVal = *ptr;
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T* fPtr;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T  fVal;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
71