|
|
|
@ -66,36 +66,116 @@ void print_bits ( T val, DFHack::Console& out )
|
|
|
|
|
out.print(strs.str().c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//FIXME: Error 8 error C4519: default template arguments are only allowed on a class template
|
|
|
|
|
template <typename CT, typename FT, typename AT/* = FT*/>
|
|
|
|
|
CT *binsearch_in_vector(std::vector<CT*> &vec, FT CT::*field, AT value)
|
|
|
|
|
/*
|
|
|
|
|
* Binary search in vectors.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
template <typename FT>
|
|
|
|
|
int binsearch_index(const std::vector<FT> &vec, FT key, bool exact = true)
|
|
|
|
|
{
|
|
|
|
|
// Returns the index of the value >= the key
|
|
|
|
|
int min = -1, max = (int)vec.size();
|
|
|
|
|
const FT *p = vec.data();
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
int mid = (min + max)>>1;
|
|
|
|
|
if (mid == min)
|
|
|
|
|
return exact ? -1 : max;
|
|
|
|
|
FT midv = p[mid];
|
|
|
|
|
if (midv == key)
|
|
|
|
|
return mid;
|
|
|
|
|
else if (midv < key)
|
|
|
|
|
min = mid;
|
|
|
|
|
else
|
|
|
|
|
max = mid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename CT, typename FT>
|
|
|
|
|
int binsearch_index(const std::vector<CT*> &vec, FT CT::*field, FT key, bool exact = true)
|
|
|
|
|
{
|
|
|
|
|
// Returns the index of the value >= the key
|
|
|
|
|
int min = -1, max = (int)vec.size();
|
|
|
|
|
CT **p = vec.data();
|
|
|
|
|
FT key = (FT)value;
|
|
|
|
|
CT *const *p = vec.data();
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
int mid = (min + max)>>1;
|
|
|
|
|
if (mid == min)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return exact ? -1 : max;
|
|
|
|
|
FT midv = p[mid]->*field;
|
|
|
|
|
if (midv == key)
|
|
|
|
|
{
|
|
|
|
|
return p[mid];
|
|
|
|
|
}
|
|
|
|
|
return mid;
|
|
|
|
|
else if (midv < key)
|
|
|
|
|
{
|
|
|
|
|
min = mid;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
max = mid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename CT>
|
|
|
|
|
inline int binsearch_index(const std::vector<CT*> &vec, typename CT::key_field_type key, bool exact = true)
|
|
|
|
|
{
|
|
|
|
|
return CT::binsearch_index(vec, key, exact);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename CT>
|
|
|
|
|
inline int binsearch_index(const std::vector<CT*> &vec, typename CT::key_pointer_type key, bool exact = true)
|
|
|
|
|
{
|
|
|
|
|
return CT::binsearch_index(vec, key, exact);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FT, typename KT>
|
|
|
|
|
inline bool vector_contains(const std::vector<FT> &vec, KT key)
|
|
|
|
|
{
|
|
|
|
|
return binsearch_index(vec, key) >= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename CT, typename FT>
|
|
|
|
|
inline bool vector_contains(const std::vector<CT*> &vec, FT CT::*field, FT key)
|
|
|
|
|
{
|
|
|
|
|
return binsearch_index(vec, field, key) >= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FT>
|
|
|
|
|
unsigned insert_into_vector(std::vector<FT> &vec, FT key, bool *inserted = NULL)
|
|
|
|
|
{
|
|
|
|
|
unsigned pos = (unsigned)binsearch_index(vec, key, false);
|
|
|
|
|
bool to_ins = (pos >= vec.size() || vec[pos] != key);
|
|
|
|
|
if (inserted) *inserted = to_ins;
|
|
|
|
|
if (to_ins)
|
|
|
|
|
vec.insert(vec.begin()+pos,key);
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename CT, typename FT>
|
|
|
|
|
unsigned insert_into_vector(std::vector<CT*> &vec, FT CT::*field, CT *obj, bool *inserted = NULL)
|
|
|
|
|
{
|
|
|
|
|
unsigned pos = (unsigned)binsearch_index(vec, field, obj->*field, false);
|
|
|
|
|
bool to_ins = (pos >= vec.size() || vec[pos] != obj);
|
|
|
|
|
if (inserted) *inserted = to_ins;
|
|
|
|
|
if (to_ins)
|
|
|
|
|
vec.insert(vec.begin()+pos,obj);
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename CT, typename KT>
|
|
|
|
|
CT *binsearch_in_vector(const std::vector<CT*> &vec, KT value)
|
|
|
|
|
{
|
|
|
|
|
int idx = binsearch_index(vec, value);
|
|
|
|
|
return idx < 0 ? NULL : vec[idx];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename CT, typename FT>
|
|
|
|
|
CT *binsearch_in_vector(const std::vector<CT*> &vec, FT CT::*field, FT value)
|
|
|
|
|
{
|
|
|
|
|
int idx = binsearch_index(vec, field, value);
|
|
|
|
|
return idx < 0 ? NULL : vec[idx];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* MISC
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the amount of milliseconds elapsed since the UNIX epoch.
|
|
|
|
|
* Works on both windows and linux.
|
|
|
|
|