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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/core/SkTSearch.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,146 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#ifndef SkTSearch_DEFINED
    1.14 +#define SkTSearch_DEFINED
    1.15 +
    1.16 +#include "SkTypes.h"
    1.17 +
    1.18 +/**
    1.19 + *  All of the SkTSearch variants want to return the index (0...N-1) of the
    1.20 + *  found element, or the bit-not of where to insert the element.
    1.21 + *
    1.22 + *  At a simple level, if the return value is negative, it was not found.
    1.23 + *
    1.24 + *  For clients that want to insert the new element if it was not found, use
    1.25 + *  the following logic:
    1.26 + *
    1.27 + *  int index = SkTSearch(...);
    1.28 + *  if (index >= 0) {
    1.29 + *      // found at index
    1.30 + *  } else {
    1.31 + *      index = ~index; // now we are positive
    1.32 + *      // insert at index
    1.33 + *  }
    1.34 + */
    1.35 +
    1.36 +
    1.37 +// The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
    1.38 +// used to perform comparisons. It has two function operators:
    1.39 +//      bool operator() (const T& t, const K& k)
    1.40 +//      bool operator() (const K& t, const T& k)
    1.41 +template <typename T, typename K, typename LESS>
    1.42 +int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& less)
    1.43 +{
    1.44 +    SkASSERT(count >= 0);
    1.45 +    if (count <= 0) {
    1.46 +        return ~0;
    1.47 +    }
    1.48 +
    1.49 +    SkASSERT(base != NULL); // base may be NULL if count is zero
    1.50 +
    1.51 +    int lo = 0;
    1.52 +    int hi = count - 1;
    1.53 +
    1.54 +    while (lo < hi) {
    1.55 +        int mid = (hi + lo) >> 1;
    1.56 +        const T* elem = (const T*)((const char*)base + mid * elemSize);
    1.57 +
    1.58 +        if (less(*elem, key))
    1.59 +            lo = mid + 1;
    1.60 +        else
    1.61 +            hi = mid;
    1.62 +    }
    1.63 +
    1.64 +    const T* elem = (const T*)((const char*)base + hi * elemSize);
    1.65 +    if (less(*elem, key)) {
    1.66 +        hi += 1;
    1.67 +        hi = ~hi;
    1.68 +    } else if (less(key, *elem)) {
    1.69 +        hi = ~hi;
    1.70 +    }
    1.71 +    return hi;
    1.72 +}
    1.73 +
    1.74 +// Adapts a less-than function to a functor.
    1.75 +template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
    1.76 +    bool operator()(const T& a, const T& b) { return LESS(a, b); }
    1.77 +};
    1.78 +
    1.79 +// Specialization for case when T==K and the caller wants to use a function rather than functor.
    1.80 +template <typename T, bool (LESS)(const T&, const T&)>
    1.81 +int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
    1.82 +    static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
    1.83 +    return SkTSearch(base, count, target, elemSize, functor);
    1.84 +}
    1.85 +
    1.86 +// Adapts operator < to a functor.
    1.87 +template <typename T> struct SkTLessFunctor {
    1.88 +    bool operator()(const T& a, const T& b) { return a < b; }
    1.89 +};
    1.90 +
    1.91 +// Specialization for T==K, compare using op <.
    1.92 +template <typename T>
    1.93 +int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
    1.94 +    static SkTLessFunctor<T> functor;
    1.95 +    return SkTSearch(base, count, target, elemSize, functor);
    1.96 +}
    1.97 +
    1.98 +// Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface take T* rather than T.
    1.99 +template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToPtrFunctorAdaptor {
   1.100 +    bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
   1.101 +};
   1.102 +
   1.103 +// Specialization for case where domain is an array of T* and the key value is a T*, and you want
   1.104 +// to compare the T objects, not the pointers.
   1.105 +template <typename T, bool (LESS)(const T&, const T&)>
   1.106 +int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
   1.107 +    static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
   1.108 +    return SkTSearch(base, count, target, elemSize, functor);
   1.109 +}
   1.110 +
   1.111 +int SkStrSearch(const char*const* base, int count, const char target[],
   1.112 +                size_t target_len, size_t elemSize);
   1.113 +int SkStrSearch(const char*const* base, int count, const char target[],
   1.114 +                size_t elemSize);
   1.115 +
   1.116 +/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
   1.117 +    base points to a table of lower-case strings.
   1.118 +*/
   1.119 +int SkStrLCSearch(const char*const* base, int count, const char target[],
   1.120 +                  size_t target_len, size_t elemSize);
   1.121 +int SkStrLCSearch(const char*const* base, int count, const char target[],
   1.122 +                  size_t elemSize);
   1.123 +
   1.124 +/** Helper class to convert a string to lower-case, but only modifying the ascii
   1.125 +    characters. This makes the routine very fast and never changes the string
   1.126 +    length, but it is not suitable for linguistic purposes. Normally this is
   1.127 +    used for buiding and searching string tables.
   1.128 +*/
   1.129 +class SkAutoAsciiToLC {
   1.130 +public:
   1.131 +    SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
   1.132 +    ~SkAutoAsciiToLC();
   1.133 +
   1.134 +    const char* lc() const { return fLC; }
   1.135 +    size_t      length() const { return fLength; }
   1.136 +
   1.137 +private:
   1.138 +    char*   fLC;    // points to either the heap or fStorage
   1.139 +    size_t  fLength;
   1.140 +    enum {
   1.141 +        STORAGE = 64
   1.142 +    };
   1.143 +    char    fStorage[STORAGE+1];
   1.144 +};
   1.145 +
   1.146 +// Helper when calling qsort with a compare proc that has typed its arguments
   1.147 +#define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)
   1.148 +
   1.149 +#endif

mercurial