kora-bot/Source/BWEM/src/utils.h

279 lines
6.6 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// This file is part of the BWEM Library.
// BWEM is free software, licensed under the MIT/X11 License.
// A copy of the license is provided with the library in the LICENSE file.
// Copyright (c) 2015, 2017, Igor Dimitrijevic
//
//////////////////////////////////////////////////////////////////////////
#ifndef BWEM_UTILS_H
#define BWEM_UTILS_H
#include <string>
#include <vector>
#include <algorithm>
#include <cstdint>
#include <limits>
#include <fstream>
#include "defs.h"
namespace BWEM {
namespace utils {
//extern std::ofstream Log;
template <class T> void unused(const T &) {}
inline int queenWiseNorm(int dx, int dy)
{
return std::max(abs(dx), abs(dy));
}
inline int squaredNorm(int dx, int dy)
{
return dx*dx + dy*dy;
}
inline double norm(int dx, int dy)
{
return sqrt(squaredNorm(dx, dy));
}
inline int scalar_product(int ax, int ay, int bx, int by)
{
return ax*bx + ay*by;
}
// Returns whether the line segments [a, b] and [c, d] intersect.
bool intersect(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy);
template<class T>
std::string my_to_string(const T & value)
{
std::ostringstream oss;
std::string res;
oss << value;
res = oss.str();
return res;
}
template<class T>
T string_to_value(const std::string & s)
{
std::istringstream iss(s);
T res;
iss >> res;
return res;
}
template<typename T>
bool from_string(const std::string & s, T & dest)
{
std::istringstream iss(s);
return !(iss >> dest).fail();
}
bool canWrite(const std::string & fileName);
// http://stackoverflow.com/questions/17224256/function-checking-if-an-integer-type-can-fit-a-value-of-possibly-different-inte
template <typename T, typename U>
bool CanTypeFitValue(const U value) {
const intmax_t botT = intmax_t(std::numeric_limits<T>::min() );
const intmax_t botU = intmax_t(std::numeric_limits<U>::min() );
const uintmax_t topT = uintmax_t(std::numeric_limits<T>::max() );
const uintmax_t topU = uintmax_t(std::numeric_limits<U>::max() );
return !( (botT > botU && value < static_cast<U> (botT)) || (topT < topU && value > static_cast<U> (topT)) );
}
// http://stackoverflow.com/questions/6942273/get-random-element-from-container-c-stl
template <typename I>
I random_element(I begin, I end)
{
const auto n = std::distance(begin, end);
const auto divisor = (RAND_MAX + 1) / n;
typename std::remove_const<decltype(n)>::type k;
do { k = std::rand() / divisor; } while (k >= n);
std::advance(begin, k);
return begin;
}
template<class T>
inline const typename T::value_type & random_element(const T & Container)
{
const auto n = Container.size();
const auto divisor = (RAND_MAX + 1) / n;
typename std::remove_const<decltype(n)>::type k;
do { k = std::rand() / divisor; } while (k >= n);
return Container[k];
}
template<class T>
inline typename T::value_type & random_element(T & Container)
{
return const_cast<typename T::value_type &>(random_element(static_cast<const T &>(Container)));
}
template<class T>
inline void really_remove(T & Container, const typename T::value_type & Element)
{
Container.erase(remove(Container.begin(), Container.end(), Element), Container.end());
}
template<class T, class Pred>
inline void really_remove_if(T & Container, Pred pred)
{
Container.erase(remove_if(Container.begin(), Container.end(), pred), Container.end());
}
template<class T, class E>
inline bool contains(const T & Container, const E & Element)
{
return find(Container.begin(), Container.end(), Element) != Container.end();
}
template<class T>
inline void fast_erase(std::vector<T> & Vector, int i)
{
bwem_assert((0 <= i) && (i < (int)Vector.size()));
std::swap(Vector[i], Vector.back());
Vector.pop_back();
}
struct compare2nd
{
template <typename T>
bool operator()(const T & a, const T & b)
{
return a.second < b.second;
}
};
//////////////////////////////////////////////////////////////////////////////////////////////
// //
// class Markable
// //
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Provides efficient marking ability.
//
// Usage: class MyNode : (public) Markable<MyNode, unsigned> {...};
//
// Note: This implementation uses a static member.
//
template<class Derived, class Mark>
class Markable
{
public:
typedef Mark mark_t;
Markable() : m_lastMark(0) {}
bool Marked() const { return m_lastMark == m_currentMark; }
void SetMarked() const { m_lastMark = m_currentMark; }
void SetUnmarked() const { m_lastMark = m_currentMark-1; }
static void UnmarkAll() { ++m_currentMark; }
private:
mutable mark_t m_lastMark;
static mark_t m_currentMark;
};
template<class Derived, class Mark>
Mark Markable<Derived, Mark>::m_currentMark = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// //
// class UserData
// //
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Provides free-to-use, intrusive data for several types of the BWEM library
// Despite their names and their types, they can be used for any purpose.
//
class UserData
{
public:
// Free use.
int Data() const { return m_data; }
void SetData(int data) const { m_data = data; }
// Free use.
void * Ptr() const { return m_ptr; }
void SetPtr(void * p) const { m_ptr = p; }
// Free use.
void * Ext() const { return m_ext; }
void SetExt(void * p) const { m_ext = p; }
protected:
UserData() = default;
UserData(const UserData &) = default;
private:
mutable void * m_ptr = nullptr;
mutable void * m_ext = nullptr;
mutable int m_data = 0;
};
}} // namespace BWEM::utils
#endif