DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

/*
 * Copyright 2008 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkPtrSet_DEFINED
#define SkPtrSet_DEFINED

#include "SkRefCnt.h"
#include "SkFlattenable.h"
#include "SkTDArray.h"

/**
 *  Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
 *  return the same ID (since its a set). Subclasses can override inPtr()
 *  and decPtr(). incPtr() is called each time a unique ptr is added ot the
 *  set. decPtr() is called on each ptr when the set is destroyed or reset.
 */
class SkPtrSet : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkPtrSet)

    /**
     *  Search for the specified ptr in the set. If it is found, return its
     *  32bit ID [1..N], or if not found, return 0. Always returns 0 for NULL.
     */
    uint32_t find(void*) const;

    /**
     *  Add the specified ptr to the set, returning a unique 32bit ID for it
     *  [1...N]. Duplicate ptrs will return the same ID.
     *
     *  If the ptr is NULL, it is not added, and 0 is returned.
     */
    uint32_t add(void*);

    /**
     *  Return the number of (non-null) ptrs in the set.
     */
    int count() const { return fList.count(); }

    /**
     *  Copy the ptrs in the set into the specified array (allocated by the
     *  caller). The ptrs are assgined to the array based on their corresponding
     *  ID. e.g. array[ptr.ID - 1] = ptr.
     *
     *  incPtr() and decPtr() are not called during this operation.
     */
    void copyToArray(void* array[]) const;

    /**
     *  Call decPtr() on each ptr in the set, and the reset the size of the set
     *  to 0.
     */
    void reset();

protected:
    virtual void incPtr(void*) {}
    virtual void decPtr(void*) {}

private:
    struct Pair {
        void*       fPtr;   // never NULL
        uint32_t    fIndex; // 1...N
    };

    // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
    // detect duplicates when add() is called. Hence we need to store the
    // ptr and its ID/fIndex explicitly, since the ptr's position in the array
    // is not related to its "index".
    SkTDArray<Pair>  fList;

    static bool Less(const Pair& a, const Pair& b);

    typedef SkRefCnt INHERITED;
};

/**
 *  Templated wrapper for SkPtrSet, just meant to automate typecasting
 *  parameters to and from void* (which the base class expects).
 */
template <typename T> class SkTPtrSet : public SkPtrSet {
public:
    uint32_t find(T ptr) {
        return this->INHERITED::find((void*)ptr);
    }
    uint32_t add(T ptr) {
        return this->INHERITED::add((void*)ptr);
    }

    void copyToArray(T* array) const {
        this->INHERITED::copyToArray((void**)array);
    }

private:
    typedef SkPtrSet INHERITED;
};

/**
 *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
 *  base class's incPtr() and decPtr() are called. This makes it a valid owner
 *  of each ptr, which is released when the set is reset or destroyed.
 */
class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
public:
    virtual ~SkRefCntSet();

protected:
    // overrides
    virtual void incPtr(void*);
    virtual void decPtr(void*);
};

class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};

/**
 * Similar to SkFactorySet, but only allows Factorys that have registered names.
 * Also has a function to return the next added Factory's name.
 */
class SkNamedFactorySet : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkNamedFactorySet)

    SkNamedFactorySet();

    /**
     * Find the specified Factory in the set. If it is not already in the set,
     * and has registered its name, add it to the set, and return its index.
     * If the Factory has no registered name, return 0.
     */
    uint32_t find(SkFlattenable::Factory);

    /**
     * If new Factorys have been added to the set, return the name of the first
     * Factory added after the Factory name returned by the last call to this
     * function.
     */
    const char* getNextAddedFactoryName();
private:
    int                    fNextAddedFactory;
    SkFactorySet           fFactorySet;
    SkTDArray<const char*> fNames;

    typedef SkRefCnt INHERITED;
};

#endif