Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkPtrSet_DEFINED
     18 #define SkPtrSet_DEFINED
     19 
     20 #include "SkRefCnt.h"
     21 #include "SkTDArray.h"
     22 
     23 /**
     24  *  Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
     25  *  return the same ID (since its a set). Subclasses can override inPtr()
     26  *  and decPtr(). incPtr() is called each time a unique ptr is added ot the
     27  *  set. decPtr() is called on each ptr when the set is destroyed or reset.
     28  */
     29 class SkPtrSet : public SkRefCnt {
     30 public:
     31     /**
     32      *  Search for the specified ptr in the set. If it is found, return its
     33      *  32bit ID [1..N], or if not found, return 0. Always returns 0 for NULL.
     34      */
     35     uint32_t find(void*) const;
     36 
     37     /**
     38      *  Add the specified ptr to the set, returning a unique 32bit ID for it
     39      *  [1...N]. Duplicate ptrs will return the same ID.
     40      *
     41      *  If the ptr is NULL, it is not added, and 0 is returned.
     42      */
     43     uint32_t add(void*);
     44 
     45     /**
     46      *  Return the number of (non-null) ptrs in the set.
     47      */
     48     int count() const { return fList.count(); }
     49 
     50     /**
     51      *  Copy the ptrs in the set into the specified array (allocated by the
     52      *  caller). The ptrs are assgined to the array based on their corresponding
     53      *  ID. e.g. array[ptr.ID - 1] = ptr.
     54      *
     55      *  incPtr() and decPtr() are not called during this operation.
     56      */
     57     void copyToArray(void* array[]) const;
     58 
     59     /**
     60      *  Call decPtr() on each ptr in the set, and the reset the size of the set
     61      *  to 0.
     62      */
     63     void reset();
     64 
     65 protected:
     66     virtual void incPtr(void* ptr) {}
     67     virtual void decPtr(void* ptr) {}
     68 
     69 private:
     70     struct Pair {
     71         void*       fPtr;   // never NULL
     72         uint32_t    fIndex; // 1...N
     73     };
     74 
     75     // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
     76     // detect duplicates when add() is called. Hence we need to store the
     77     // ptr and its ID/fIndex explicitly, since the ptr's position in the array
     78     // is not related to its "index".
     79     SkTDArray<Pair>  fList;
     80 
     81     static int Cmp(const Pair& a, const Pair& b);
     82 
     83     typedef SkRefCnt INHERITED;
     84 };
     85 
     86 /**
     87  *  Templated wrapper for SkPtrSet, just meant to automate typecasting
     88  *  parameters to and from void* (which the base class expects).
     89  */
     90 template <typename T> class SkTPtrSet : public SkPtrSet {
     91 public:
     92     uint32_t add(T ptr) {
     93         return this->INHERITED::add((void*)ptr);
     94     }
     95 
     96     void copyToArray(T* array) const {
     97         this->INHERITED::copyToArray((void**)array);
     98     }
     99 
    100 private:
    101     typedef SkPtrSet INHERITED;
    102 };
    103 
    104 #endif
    105