
/*
 * Copyright 2006 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 SkTSearch_DEFINED
#define SkTSearch_DEFINED

#include "SkTypes.h"

/**
 *  All of the SkTSearch variants want to return the index (0...N-1) of the
 *  found element, or the bit-not of where to insert the element.
 *
 *  At a simple level, if the return value is negative, it was not found.
 *
 *  For clients that want to insert the new element if it was not found, use
 *  the following logic:
 *
 *  int index = SkTSearch(...);
 *  if (index >= 0) {
 *      // found at index
 *  } else {
 *      index = ~index; // now we are positive
 *      // insert at index
 *  }
 */


// The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
// used to perform comparisons. It has two function operators:
//      bool operator() (const T& t, const K& k)
//      bool operator() (const K& t, const T& k)
template <typename T, typename K, typename LESS>
int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& less)
{
    SkASSERT(count >= 0);
    if (count <= 0) {
        return ~0;
    }

    SkASSERT(base != NULL); // base may be NULL if count is zero

    int lo = 0;
    int hi = count - 1;

    while (lo < hi) {
        int mid = lo + ((hi - lo) >> 1);
        const T* elem = (const T*)((const char*)base + mid * elemSize);

        if (less(*elem, key))
            lo = mid + 1;
        else
            hi = mid;
    }

    const T* elem = (const T*)((const char*)base + hi * elemSize);
    if (less(*elem, key)) {
        hi += 1;
        hi = ~hi;
    } else if (less(key, *elem)) {
        hi = ~hi;
    }
    return hi;
}

// Adapts a less-than function to a functor.
template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
    bool operator()(const T& a, const T& b) { return LESS(a, b); }
};

// Specialization for case when T==K and the caller wants to use a function rather than functor.
template <typename T, bool (LESS)(const T&, const T&)>
int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
    static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
    return SkTSearch(base, count, target, elemSize, functor);
}

// Adapts operator < to a functor.
template <typename T> struct SkTLessFunctor {
    bool operator()(const T& a, const T& b) { return a < b; }
};

// Specialization for T==K, compare using op <.
template <typename T>
int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
    static SkTLessFunctor<T> functor;
    return SkTSearch(base, count, target, elemSize, functor);
}

// Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface take T* rather than T.
template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToPtrFunctorAdaptor {
    bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
};

// Specialization for case where domain is an array of T* and the key value is a T*, and you want
// to compare the T objects, not the pointers.
template <typename T, bool (LESS)(const T&, const T&)>
int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
    static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
    return SkTSearch(base, count, target, elemSize, functor);
}

int SkStrSearch(const char*const* base, int count, const char target[],
                size_t target_len, size_t elemSize);
int SkStrSearch(const char*const* base, int count, const char target[],
                size_t elemSize);

/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
    base points to a table of lower-case strings.
*/
int SkStrLCSearch(const char*const* base, int count, const char target[],
                  size_t target_len, size_t elemSize);
int SkStrLCSearch(const char*const* base, int count, const char target[],
                  size_t elemSize);

/** Helper class to convert a string to lower-case, but only modifying the ascii
    characters. This makes the routine very fast and never changes the string
    length, but it is not suitable for linguistic purposes. Normally this is
    used for buiding and searching string tables.
*/
class SkAutoAsciiToLC {
public:
    SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
    ~SkAutoAsciiToLC();

    const char* lc() const { return fLC; }
    size_t      length() const { return fLength; }

private:
    char*   fLC;    // points to either the heap or fStorage
    size_t  fLength;
    enum {
        STORAGE = 64
    };
    char    fStorage[STORAGE+1];
};

// Helper when calling qsort with a compare proc that has typed its arguments
#define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)

#endif
