Files
MagicSetEditor2/src/util/order_cache.hpp
T
coppro 26562e03e3 Updated copyright information - added my name and also changed 2007 to 2008
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@837 0fc631ac-6414-0410-93d0-97cfa31319b6
2008-04-06 18:16:32 +00:00

88 lines
3.4 KiB
C++

//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_UTIL_ORDER_CACHE
#define HEADER_UTIL_ORDER_CACHE
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
// ----------------------------------------------------------------------------- : OrderCache
/// Object that cashes an ordered version of a list of items, for finding the position of objects
/** Can be used as a map "void* -> int" for finding the position of an object */
template <typename T>
class OrderCache : public IntrusivePtrBase<OrderCache<T> > {
public:
/// Initialize the order cache, ordering the keys by their string values from the other vector
/** Optionally filter the list using a vector of booleans of items to keep (note: vector<bool> is evil)
* @pre keys.size() == values.size()
*/
OrderCache(const vector<T>& keys, const vector<String>& values, vector<int>* keep = nullptr);
/// Find the position of the given key in the cache, returns -1 if not found
int find(const T& key) const;
private:
struct CompareKeys;
struct CompareValues;
typedef pair<void*,int> KV;
vector<KV> positions;
};
// ----------------------------------------------------------------------------- : Implementation
template <typename T>
struct OrderCache<T>::CompareKeys {
inline bool operator () (const KV& a, void* b) { return a.first < b; }
inline bool operator () (const KV& a, const KV& b) { return a.first < b.first; }
inline bool operator () (void* a, const KV& b) { return a < b.first; }
};
template <typename T>
struct OrderCache<T>::CompareValues {
const vector<String>& values;
CompareValues(const vector<String>& values) : values(values) {}
inline bool operator () (const KV& a, const KV& b) {
return smart_less(values[a.second], values[b.second]);
}
};
template <typename T>
OrderCache<T>::OrderCache(const vector<T>& keys, const vector<String>& values, vector<int>* keep) {
assert(keys.size() == values.size());
assert(!keep || keep->size() == keys.size());
// initialize positions, use pos to point back to the values vector
positions.reserve(keys.size());
int i = 0;
for (typename vector<T>::const_iterator it = keys.begin() ; it != keys.end() ; ++it, ++i) {
if (!keep || (*keep)[i]) {
positions.push_back(KV(&**it, i));
}
}
// sort the KVs by the values
sort(positions.begin(), positions.end(), CompareValues(values));
// update positions, to point to sorted list
i = 0;
for (typename vector<KV>::iterator it = positions.begin() ; it != positions.end() ; ++it, ++i) {
it->second = i;
}
// sort the KVs by the keys
sort(positions.begin(), positions.end(), CompareKeys());
}
template <typename T>
int OrderCache<T>::find(const T& key) const {
vector<KV>::const_iterator it = lower_bound(positions.begin(), positions.end(), &*key, CompareKeys());
if (it == positions.end() || it->first != &*key) return -1;
return it->second;
}
// ----------------------------------------------------------------------------- : EOF
#endif