gfx/skia/trunk/include/core/SkTLazy.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2011 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    11 #ifndef SkTLazy_DEFINED
    12 #define SkTLazy_DEFINED
    14 #include "SkTypes.h"
    15 #include <new>
    17 template <typename T> class SkTLazy;
    18 template <typename T> void* operator new(size_t, SkTLazy<T>* lazy);
    20 /**
    21  *  Efficient way to defer allocating/initializing a class until it is needed
    22  *  (if ever).
    23  */
    24 template <typename T> class SkTLazy {
    25 public:
    26     SkTLazy() : fPtr(NULL) {}
    28     explicit SkTLazy(const T* src) : fPtr(NULL) {
    29         if (src) {
    30             fPtr = new (fStorage) T(*src);
    31         }
    32     }
    34     SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
    35         if (src.isValid()) {
    36             fPtr = new (fStorage) T(*src->get());
    37         } else {
    38             fPtr = NULL;
    39         }
    40     }
    42     ~SkTLazy() {
    43         if (this->isValid()) {
    44             fPtr->~T();
    45         }
    46     }
    48     /**
    49      *  Return a pointer to a default-initialized instance of the class. If a
    50      *  previous instance had been initialized (either from init() or set()) it
    51      *  will first be destroyed, so that a freshly initialized instance is
    52      *  always returned.
    53      */
    54     T* init() {
    55         if (this->isValid()) {
    56             fPtr->~T();
    57         }
    58         fPtr = new (SkTCast<T*>(fStorage)) T;
    59         return fPtr;
    60     }
    62     /**
    63      *  Copy src into this, and return a pointer to a copy of it. Note this
    64      *  will always return the same pointer, so if it is called on a lazy that
    65      *  has already been initialized, then this will copy over the previous
    66      *  contents.
    67      */
    68     T* set(const T& src) {
    69         if (this->isValid()) {
    70             *fPtr = src;
    71         } else {
    72             fPtr = new (SkTCast<T*>(fStorage)) T(src);
    73         }
    74         return fPtr;
    75     }
    77     /**
    78      * Destroy the lazy object (if it was created via init() or set())
    79      */
    80     void reset() {
    81         if (this->isValid()) {
    82             fPtr->~T();
    83             fPtr = NULL;
    84         }
    85     }
    87     /**
    88      *  Returns true if a valid object has been initialized in the SkTLazy,
    89      *  false otherwise.
    90      */
    91     bool isValid() const { return NULL != fPtr; }
    93     /**
    94      * Returns the object. This version should only be called when the caller
    95      * knows that the object has been initialized.
    96      */
    97     T* get() const { SkASSERT(this->isValid()); return fPtr; }
    99     /**
   100      * Like above but doesn't assert if object isn't initialized (in which case
   101      * NULL is returned).
   102      */
   103     T* getMaybeNull() const { return fPtr; }
   105 private:
   106     friend void* operator new<T>(size_t, SkTLazy* lazy);
   108     T*   fPtr; // NULL or fStorage
   109     char fStorage[sizeof(T)];
   110 };
   112 // Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly
   113 template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) {
   114     SkASSERT(!lazy->isValid());
   115     lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage);
   116     return lazy->fPtr;
   117 }
   119 // Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
   120 // to match the op new silences warnings about missing op delete when a constructor throws an
   121 // exception.
   122 template <typename T> void operator delete(void*, SkTLazy<T>*) { SK_CRASH(); }
   124 // Use this to construct a T inside an SkTLazy using a non-default constructor.
   125 #define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args)
   127 /**
   128  * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized
   129  * with a const pointer but provides a non-const pointer accessor. The first time the
   130  * accessor is called (if ever) the object is cloned.
   131  *
   132  * In the following example at most one copy of constThing is made:
   133  *
   134  * SkTCopyOnFirstWrite<Thing> thing(&constThing);
   135  * ...
   136  * function_that_takes_a_const_thing_ptr(thing); // constThing is passed
   137  * ...
   138  * if (need_to_modify_thing()) {
   139  *    thing.writable()->modifyMe(); // makes a copy of constThing
   140  * }
   141  * ...
   142  * x = thing->readSomething();
   143  * ...
   144  * if (need_to_modify_thing_now()) {
   145  *    thing.writable()->changeMe(); // makes a copy of constThing if we didn't call modifyMe()
   146  * }
   147  *
   148  * consume_a_thing(thing); // could be constThing or a modified copy.
   149  */
   150 template <typename T>
   151 class SkTCopyOnFirstWrite {
   152 public:
   153     SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
   155     // Constructor for delayed initialization.
   156     SkTCopyOnFirstWrite() : fObj(NULL) {}
   158     // Should only be called once, and only if the default constructor was used.
   159     void init(const T& initial) {
   160         SkASSERT(NULL == fObj);
   161         SkASSERT(!fLazy.isValid());
   162         fObj = &initial;
   163     }
   165     /**
   166      * Returns a writable T*. The first time this is called the initial object is cloned.
   167      */
   168     T* writable() {
   169         SkASSERT(NULL != fObj);
   170         if (!fLazy.isValid()) {
   171             fLazy.set(*fObj);
   172             fObj = fLazy.get();
   173         }
   174         return const_cast<T*>(fObj);
   175     }
   177     /**
   178      * Operators for treating this as though it were a const pointer.
   179      */
   181     const T *operator->() const { return fObj; }
   183     operator const T*() const { return fObj; }
   185     const T& operator *() const { return *fObj; }
   187 private:
   188     const T*    fObj;
   189     SkTLazy<T>  fLazy;
   190 };
   192 #endif

mercurial