// Revision 1.41 2000/01/23 14:09:36 eyalk
// adding error macros + minmax for three elements + change in split()
// and unary_wrapper() functions.
//
// Revision 1.40 1999/10/04 08:23:19 eyalk
// epsilon added
//
// Revision 1.39 1999/07/14 06:20:53 joseph-w
// fixing dependencies
//
// Revision 1.38 1999/06/10 12:04:37 eyalk
// changes before new scanner version
//
// Revision 1.37 1999/04/20 06:55:43 eyalk
// reference to pair type
//
// Revision 1.36 1999/02/16 08:08:48 eyalk
// oop small change
//
// Revision 1.35 1999/02/14 08:58:39 eyalk
// make diff to view changes ...
//
// Revision 1.34 1999/02/04 12:22:40 eyalk
// removing destructor from singleton (have no friends)
//
// Revision 1.33 1999/02/04 11:40:06 eyalk
// template singleton in ey_basics.H
//
// Revision 1.32 1998/12/15 14:37:43 eyalk
// small changes
//
// Revision 1.31 1998/12/15 11:11:09 tamir
// added ifndef for macros : ABS, SDR
//
// Revision 1.30 1998/10/29 09:03:22 joseph-w
// c++ fixes
//
// Revision 1.29 1998/08/24 15:14:58 joseph-w
// fixed timer const warnings
//
// Revision 1.28 1998/08/13 07:35:54 eyalk
// fixing ntos %f -> %g
//
// Revision 1.27 1998/08/09 17:01:36 yaelm
// change <algo.h> to <algorithm>
//
// Revision 1.26 1998/08/04 07:12:52 eyalk
// removing MIN cosmetic changes in box_finder
//
// Revision 1.25 1998/08/03 14:52:42 eyalk
// Aug. 3 98
//
// Revision 1.24 1998/07/21 08:02:58 joseph-w
// #DEFINE word ... conflict with solaris system includes.
//
// Revision 1.23 1998/05/27 12:03:41 eyalk
// Explicit class + rearranging
//
// Revision 1.22 1998/05/19 11:41:30 eyalk
// using iterator_traits
//
// Revision 1.21 1998/04/20 11:38:47 eyalk
// version 2.8.1 adaptations + restructuring
//
// Revision 1.20 1998/03/03 10:09:30 eyalk
// upgrading to gcc2.8.0 and making changes due to panic flagged compilation
//
// Revision 1.19 1998/02/23 15:44:54 eyalk
// printing vector paded with #ifdef for back compatibility with non 2.8 gcc
//
// Revision 1.18 1998/02/23 15:02:26 meirm
// *** empty log message ***
//
// Revision 1.16 1998/02/17 15:27:19 meirm
// changing of compiler to 2.8.0
//
// Revision 1.15 1998/02/17 08:39:26 eyalk
// changes fo the g++ 2.8.0 (typename)
//
// Revision 1.14 1997/11/18 12:38:31 eyalk
// more care to correct machine parameters calculations (using atan2)
// reading map and cosmetics
//
// Revision 1.13 1997/09/11 08:49:17 eyalk
// *** empty log message ***
//
// Revision 1.12 1997/07/29 16:18:35 eyalk
// more functios
//
// Revision 1.11 1997/06/15 12:38:03 eyalk
// Moving points unification to ey_geometry.H and adding printing of list.
//
// Revision 1.10 1997/05/08 07:01:10 eyalk
// more changes
//
// Revision 1.9 1997/04/30 12:51:56 shai
// Changed operator()(const PointType& p0, const PointType& p1) of tk_segment.
//
// Revision 1.8 1997/04/30 08:52:18 shai
// Added tag to tk_segment members.
//
// Revision 1.7 1997/04/15 17:14:58 eyalk
// code improvements
//
// Revision 1.6 1997/03/02 15:19:09 eyalk
// adding the for_each algo.h and returning the SQR SQRDIST ...
//
// Revision 1.5 1997/02/19 07:21:00 eyalk
// updating files for the focus version which have z axis abilities
//
// Revision 1.4 1997/01/22 15:39:52 eyalk
// add constructor to Efeature
//
// Revision 1.3 1997/01/22 14:13:53 shmulik
// Changing the name of Feature class to Efeature
//
// Revision 1.2 1997/01/21 12:50:23 eyalk
// much more templated
//
// Revision 1.1 1996/10/24 09:36:49 eyalk
// Header files which are necessary while working with Eyal classes.
//
// Revision 1.2 1996/05/12 11:20:34 eyalk
// adding to STL the possibility to print any vector.
// correcting the transformation by adding +.5 for rounding.
//
// Revision 1.1 1996/05/05 16:32:26 eyalk
// Initial revision
//
#ifndef _EY_BASICS_HEADER_
#define _EY_BASICS_HEADER_
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cfloat>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <utility>
#include <functional>
#include <iterator>
using namespace std;
// commented out by yossi ... causes a compile error with
// system header files sys/fault.h on solaris
//
// Not used anywhere here anyway!!!
//
//#define byte unsigned char
//#define word unsigned short int
//#define dword unsigned int
// Error
// macros for fast computation (it apparently faster than inline ...)
#ifndef ABS
#define ABS(x) ((x) < 0 ? -(x) : (x))
#endif
#define ABS_DIFF(a, b) ((a) < (b) ? (b) - (a) : (a) - (b)) // abs(a - b)
#ifndef SQR
#define SQR(x) ((x)*(x))
#endif
#define SQR_DIST(p1, p2) (SQR((p1).x - (p2).x)+SQR((p1).y - (p2).y))
#define BUGPLACE " File: " << __FILE__ << " Line: " << __LINE__ << endl
#define EY_FATAL_ERROR(x) { cerr << "Error, " << (x) << BUGPLACE; exit(1); }
#define EY_WARNING(x) { cerr << "Warning, " << (x) << BUGPLACE; }
// many times rise a need for min/max for three parameters
template <class T>
inline const T& min(const T& a, const T& b, const T& c)
{
if (a < b) {
if (c < a)
return c;
else
return a;
} else {
if (c < b)
return c;
else
return b;
}
}
template <class T>
inline const T& max(const T& a, const T& b, const T& c)
{
if (b < a) {
if (a < c)
return c;
else
return a;
} else {
if (b < c)
return c;
else
return b;
}
}
inline double min(double a,double b)
{
return (a<b) ? a : b;
}
template <class T, class Compare>
inline const T& min(const T& a, const T& b, const T& c, Compare comp)
{
if (comp(a,b)) {
if (comp(c,a))
return c;
else
return a;
} else {
if (comp(c,b))
return c;
else
return b;
}
}
template <class T, class Compare>
inline const T& max(const T& a, const T& b, const T& c, Compare comp)
{
if (b,a) {
if (comp(a,c))
return c;
else
return a;
} else {
if (comp(b,c))
return c;
else
return b;
}
}
// float epsilon
const double ey_epsilon = FLT_EPSILON;
/** When casting numbers if necessary numbers are truncated when moving
from float type to integer one.
The following classes allow numbers to be round instead truncated in these
cases.
*/
// cast any type by rounding
template <class T>
struct round_cast : unary_function<T, long double> {
T operator()(long double d) {
if (d > 0)
return static_cast<T>(d + .5);
else
return static_cast<T>(d - .5);
}
};
// specialization for float
template <>
struct round_cast<float> : unary_function<float, void>{
template <class T>
float operator () (const T& a) { return static_cast<float>(a); }
};
// specialization for double
template <>
struct round_cast<double> : unary_function<double, void> {
template <class T>
double operator () (const T& a) { return static_cast<double>(a); }
};
// specialization for long double
template <>
struct round_cast<long double> : unary_function <long double, void> {
template <class T>
long double operator () (const T& a) { return static_cast<long double>(a); }
};
// prettier() function causes an object to be print pretty
// iff it has the method - ostream& pretty_print(ostream& out) const {}
// there you should define your pretty printing
template <class T>
class __pretty_print {
const T& obj;
public:
__pretty_print(T pobj) : obj(pobj) { }
friend ostream& operator << (ostream& out, const __pretty_print<T>& pobj)
{
return pobj.obj.pretty_print(out);
}
};
template<class T>
inline __pretty_print<T> prettier(const T& x) { return __pretty_print<T>(x); }
// printing vector (vertically).
template <class T>
inline ostream& operator << (ostream& out, const vector<T>& v)
{
for (vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
out << *it << endl;
}
return out;
}
// printing list (vertically)
template <class T>
inline ostream& operator << (ostream& out, const list<T>& l)
{
for (list<T>::const_iterator it = l.begin(); it != l.end(); ++it) {
out << *it << endl;
}
return out;
}
// printing map (vertically key + type).
template <class Key, class T, class Compare>
inline ostream& operator << (ostream& out, const map<Key, T, Compare>& m)
{
for (map<Key, T, Compare>::const_iterator it = m.begin(); it != m.end(); ++it) {
out << *it << endl;
}
return out;
}
// reading map
template <class Key, class T, class Compare>
inline istream& operator >> (istream& in, map<Key, T, Compare>& m)
{
pair<Key, T> tmp;
while(in >> tmp)
m[tmp.first] = tmp.second;
return in;
}
// printing container which contains containers
template <class ContainerContainer>
void container_of_containers_print(const ContainerContainer& cc,
ostream& out, char* sep1, char* sep2)
{
for (typename ContainerContainer::const_iterator it = cc.begin(); it != cc.end(); ++it) {
copy((*it).begin(), (*it).end(),
ostream_iterator<typename ContainerContainer::value_type::value_type>(out, sep2));
out << sep1;
}
}
template <class PointType>
class tk_segment {
ostream& out;
string color;
int width;
string tag;
public:
tk_segment(ostream& o, const string& c = string("black"),
int w = 1, string t = "")
: out(o), color(c), width(w), tag(t)
{}
void operator()(const PointType& p0, const PointType& p1)
{
out << "$c create line " << p0 << " " << p1
<< " -fill " << color << " -width " << width;
if(tag != "")
out << " -tag " << tag << endl;
else
out << endl;
}
void operator()(const pair<PointType, PointType>& s)
{
(*this)(s.first, s.second);
}
};
// ---------------------- adding to pair -------------------
// comparing pair by first using the second field
template <class PairType>
class less_second_first : binary_function<PairType, PairType, bool> {
public:
bool operator()(const PairType& a, const PairType& b) const {
return a.second < b.second || (!(b.second < a.second) && a.first < b.first);
}
};
// printing pair
template <class T1, class T2>
inline ostream& operator << (ostream& out, const pair<T1, T2>& p)
{
out << p.first << " " << p.second;
return out;
}
// reading pair
template <class T1, class T2>
inline istream& operator >> (istream& in, pair<T1, T2>& p)
{
in >> p.first >> p.second;
return in;
}
// act as reference to pair
template <class T1, class T2>
struct ref_pair {
typedef T1 first_type;
typedef T2 second_type;
const T1& first;
const T2& second;
ref_pair (const T1& a, const T2& b)
: first (a), second (b) {}
ref_pair(const pair<T1, T2>& p): first(p.first), second (p.second) {}
// template<class U, class V>
//ref_pair(const pair<U, V> &p): first(p.first), second (p.second) {}
private:
ref_pair();
};
template <class T1, class T2>
inline bool operator< (const ref_pair<T1, T2>& x, const ref_pair<T1, T2>& y)
{ return x.first < y.first || (! (y.first < x.first) && x.second < y.second); }
template <class T1, class T2>
inline ref_pair<T1, T2> make_ref_pair (const T1& x, const T2& y)
{ return ref_pair<T1, T2> (x, y); }
// namespace eyk {
// // triple is nacessary many times
// template <class T1, class T2 = T1, class T3 = T2>
// struct triple {
// T1 first;
// T2 second;
// T3 third;
// triple (const T1& a, const T2& b, const T3& c) :
// first (a), second (b), third (c) {}
// };
// template <class T1, class T2, class T3>
// inline bool operator== (const triple<T1, T2, T3>& x, const triple<T1, T2, T3>& y)
// { return x.first == y.first && x.second == y.second && x.third == y.third; }
// template <class T1, class T2, class T3>
// inline bool operator< (const triple<T1, T2, T3>& x, const triple<T1, T2, T3>& y)
// {
// return x.first < y.first ||
// (! (y.first < x.first) && (x.second < y.second ||
// (! y.second < x.second) && (x.third < y.third)));
// }
// template <class T1, class T2, class T3>
// inline triple<T1, T2, T3> make_triple (const T1& x, const T2& y, const T3& z)
// { return triple<T1, T2, T3> (x, y, z); }
// }
/** function object for printing container with index where start
is the strating index
*/
template <class T>
class print_index : public unary_function<T, void> {
int i;
ostream& o;
const char* d;
public:
print_index(ostream& out, const char *delimiter, int start = 0)
: i(start), o(out), d(delimiter)
{}
void operator() (T x) { o << i++ << " " << x << d; }
};
/** A very simple timer */
class Timer {
public:
// construct timer - if start=true (which is the default)
// it also start it.
Timer(bool start = true)
: last_val(0), accumulated_time(0), work_status(start)
{
if (start)
last_val = clock();
};
// reset the clock and cause it run
void reset() {
accumulated_time = 0;
work_status = true;
last_val = clock();
}
// reset the clock and stop it
void reset_stop() {
accumulated_time = 0;
work_status = false;
}
// read current time
float read_time() const {
if (work_status == true) {
accumulated_time += clock() - last_val;
last_val = clock();
}
return (float)accumulated_time/CLOCKS_PER_SEC;
}
// start the clock again after it stopped
bool start() {
if (work_status == true) {
cerr << "warrning: clock restarted while it was already worked\n";
return false;
}
work_status = true;
last_val = clock();
return true;
}
// stop the clock (not reset it)
bool stop() {
if (work_status == false) {
cerr << "warrning: clock stoped while it was not worked\n";
return false;
}
accumulated_time += clock() - last_val;
work_status = false;
return true;
}
friend ostream& operator << (ostream& out, const Timer & timer)
{
out << timer.read_time();
return out;
}
private:
mutable clock_t last_val;
mutable clock_t accumulated_time;
bool work_status;
};
// ------------------------ string manipulations ------------------
// convert number to string
inline string ntos(double num)
{
char buf[1024];
sprintf(buf, "%g", num);
return string(buf);
}
// split string according to a seperator and push_back them to a container.
// returns the number of strings and put to the container.
template <class Container>
unsigned split(const string &str, Container& result, const string& seperators)
{
result.erase(result.begin(), result.end());
bool seperator = true;
// pass over the characters of the string
for (string::const_iterator str_it = str.begin(); str_it != str.end(); ++str_it) {
// search if current char is a seperator
if (seperators.find(*str_it) != string::npos) {
// seperator found
if (!seperator) {
// previous char was not a seperator
seperator = true;
}
} else {
// character found
if (seperator) {
// previous char was a seperator
seperator = false;
result.push_back(string());
result.back() += *str_it;
} else {
// previous char was not a seperator
// just add char to last string
result.back() += *str_it;
}
}
}
return result.size();
}
// join strings from a container according to a seperator to one string.
// return string
template <class Container>
string join(const Container& input, const string& seperator,int sep_num)
{
if(input.empty())
return "";
string result = "";
for (typename Container::const_iterator iter = input.begin(); iter != input.end(); ++iter) {
result += (*iter) + (sep_num>0?seperator:"");
sep_num--;
}
return result;
}
// ----------------- wrappers ------------------------
/** create templated singleton - single global instance of a required
class.
*/
template <class T>
class singleton {
public:
// The instance
static T& i() {
static T v;
return v;
}
private:
singleton() { };
singleton(const singleton&);
};
/** Explicit class allows desired class only to be pass.
It is by forbidding others to be pass.
e.g. function f(Explicit<unsigned>) will be called
only by f(unsigned()) (or f(const unsigned()))
*/
template <class T>
class Explicit {
public:
// constructor (allows implicit conversions from T to Explicit)
Explicit(T) {}
// constructor for others wich calls non existing function by that
// disallow conversions (revealed only in link time)
template <class OTHERS>
Explicit(OTHERS)
{
// will appear as error while linking
Explicit_class_forbids_passing_type_not_desigend_to();
}
};
// Wrappers for object functions. permits the wrapped objects to be
// passed to algorithms without being copied, thus contains data that
// the algorithm may changed.
// It is like call by reference object function.
template <class Object>
class unary_wrapper : public unary_function<typename Object::argument_type,
typename Object::result_type>
{
Object& obj;
public:
unary_wrapper(Object& o) : obj(o) {}
typename Object::result_type operator()(typename Object::argument_type & a)
{
return obj(a);
}
};
// use the unary_wrap() function to wrap unary object function.
template<class Object>
unary_wrapper<Object> unary_wrap(Object& obj)
{
return unary_wrapper<Object>(obj);
}
template <class Object>
class binary_wrapper
: public binary_function<typename Object::first_argument_type,
typename Object::second_argument_type,
typename Object::result_type>
{
Object& obj;
public:
binary_wrapper(Object& o) : obj(o) {}
typename Object::result_type operator()
(typename Object::first_argument_type& a,
typename Object::second_argument_type& b)
{
return obj(a, b);
}
};
// use the binary_wrap() function to wrap binary object function.
template<class Object>
binary_wrapper<Object> binary_wrap(Object& obj)
{
return binary_wrapper<Object>(obj);
}
// --------------------------- STL like --------------------------
// to algorithm
template <class InputIterator1, class InputIterator2, class Function>
Function for_each(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, Function f)
{
while (first1 != last1) f(*first1++, *first2++);
return f;
}
// transform container to itself
template <class InputIterator, class UnaryOperation>
void transform(InputIterator first, InputIterator last, UnaryOperation op) {
for ( ; first != last; ++first)
*first = op(*first);
}
// to functional
// object function having both unary_function and binary_function versions
template <class Arg1, class Arg2, class Result>
struct dual_function {
typedef Arg1 argument_type;
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
template <class Function>
class func_insert_iterator {
protected:
Function func;
public:
typedef output_iterator_tag iterator_category;
typedef typename Function::argument_type value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit func_insert_iterator(Function f) : func(f) {}
func_insert_iterator<Function>&
operator=(const value_type& value) {
func(value);
return *this;
}
func_insert_iterator<Function>& operator*() { return *this; }
func_insert_iterator<Function>& operator++() { return *this; }
func_insert_iterator<Function>& operator++(int) { return *this; }
};
template <class Function>
inline func_insert_iterator<Function> func_inserter(Function f) {
return func_insert_iterator<Function>(f);
}
template <class Container>
class Back_insert_iterator {
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef typename Container::value_type value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit Back_insert_iterator(Container& x) : container(&x) {}
Back_insert_iterator<Container>&
operator=(const value_type& value) {
container->push_back(value);
return *this;
}
Back_insert_iterator<Container>& operator*() { return *this; }
Back_insert_iterator<Container>& operator++() { return *this; }
Back_insert_iterator<Container>& operator++(int) { return *this; }
};
template <class Container>
inline Back_insert_iterator<Container> Back_inserter(Container& x) {
return Back_insert_iterator<Container>(x);
}
#endif // _EY_BASICS_HEADER_