#ifndef KUTILITY_GENERAL_H
#define KUTILITY_GENERAL_H
#if !defined(WIN32) && !defined(_WIN32)
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#if defined(WIN32) || defined(_WIN32)
#define strncasecmp _strnicmp
#pragma warning( disable : 4244 4305 )
#endif
#include "kutility/interaction.h"
#include "string.h"
namespace kutility
{
struct kpoint
{
int x;
int y;
};
template<class T>
class rectangle
{
public:
T lx, ux, ly, uy;
T dx, dy;
rectangle(T xl, T xu, T yl, T yu) { lx=xl; ux=xu; ly=yl; uy=yu; dx=ux-lx; dy=uy-ly; };
rectangle() { lx = ux = ly = uy = dx = dy = 0; };
};
inline bool is_line( const char* str1, const char* str2 )
{
return !strncasecmp(str1, str2, strlen(str2));
}
template<class T1, class T2, class T3> inline
bool is_inside(T1 x, T2 lx, T3 ux, bool le=true, bool ue=false)
{
if( ( ((lx<x)&&(!le)) || ((lx<=x)&&le) ) && ( ((x<ux)&&(!ue)) || ((x<=ux)&&ue) ) )
{
return true;
}
else
{
return false;
}
}
template<class T1, class T2, class T3> inline
bool is_inside(T1 x, T2 lx, T3 ux, T1 y, T2 ly, T3 uy, bool le=true, bool ue=false, char oper='&')
{
switch( oper )
{
case '|':
if( is_inside(x,lx,ux,le,ue) || is_inside(y,ly,uy,le,ue) )
return true;
return false;
default:
if( is_inside(x,lx,ux,le,ue) && is_inside(y,ly,uy,le,ue) )
return true;
return false;
}
}
template<class T1, class T2> inline
bool is_inside(T1 x, T1 y, rectangle<T2> roi, bool le=true, bool ue=false, char oper='&')
{
switch( oper )
{
case '|':
if( is_inside(x,roi.lx,roi.ux,le,ue) || is_inside(y,roi.ly,roi.uy,le,ue) )
return true;
return false;
default:
if( is_inside(x,roi.lx,roi.ux,le,ue) && is_inside(y,roi.ly,roi.uy,le,ue) )
return true;
return false;
}
}
template<class T1, class T2, class T3> inline
bool is_outside(T1 x, T2 lx, T3 ux, bool le=true, bool ue=false)
{
return !(is_inside(x,lx,ux,le,ue));
}
template<class T1, class T2, class T3> inline
bool is_outside(T1 x, T2 lx, T3 ux, T1 y, T2 ly, T3 uy, bool le=true, bool ue=false, char oper='|')
{
switch( oper )
{
case '&':
if( is_outside(x,lx,ux,le,ue) && is_outside(y,ly,uy,le,ue) )
return true;
return false;
default:
if( is_outside(x,lx,ux,le,ue) || is_outside(y,ly,uy,le,ue) )
return true;
return false;
}
}
template<class T1, class T2> inline
bool is_outside(T1 x, T1 y, rectangle<T2> roi, bool le=true, bool ue=false, char oper='|')
{
switch( oper )
{
case '&':
if( is_outside(x,roi.lx,roi.ux,le,ue) && is_outside(y,roi.ly,roi.uy,le,ue) )
return true;
return false;
default:
if( is_outside(x,roi.lx,roi.ux,le,ue) || is_outside(y,roi.ly,roi.uy,le,ue) )
return true;
return false;
}
}
inline void wait_key()
{
char c;
std::cout<<"\nkey in an input to continue ";
std::cin>>c;
}
template<class T> inline
void expand_array( T* &array, int size, int nsize )
{
T* out = new T[nsize];
memcpy( out, array, size*sizeof(T) );
delete []array;
array = out;
}
template<class T> inline
T* allocate(const int sz)
{
T* array = new T[sz];
return array;
}
template<class T> inline
T** allocate(const int ysz, const int xsz)
{
T** mat = new T*[ysz];
int i;
for(i=0; i<ysz; i++ )
mat[i] = new T[xsz];
return mat;
}
template<class T> inline
void deallocate(T* &array)
{
delete[] array;
array = NULL;
}
template<class T> inline
void deallocate(T** &mat, int ysz)
{
if( mat == NULL ) return;
for(int i=0; i<ysz; i++)
deallocate(mat[i]);
delete[] mat;
mat = NULL;
}
template<class T> inline
T* clone( T* src, int sz)
{
T* dst = allocate<T>(sz);
memcpy( dst, src, sizeof(T)*sz);
return dst;
}
template<class T> inline
T** clone( T** src, int r, int c)
{
T** dst = allocate<T>(r,c);
for( int i=0; i<r; i++ )
memcpy( dst[i], src[i], sizeof(T)*c);
return dst;
}
template<class T> inline
void copy( T* dst, T* src, int sz)
{
memcpy( dst, src, sizeof(T)*sz);
}
template<class T> inline
void copy( T** dst, T** src, int ysz, int xsz)
{
int y;
for( y=0; y<ysz; y++ )
memcpy( dst[y], src[y], sizeof(T)*xsz);
}
template<class T1, class T2> inline
T1* type_cast(T2* data, int sz)
{
T1* out = new T1[sz];
for( int i=0; i<sz; i++ )
out[i] = (T1)data[i];
return out;
}
char* strrev(char* szT);
char* itoa(int value, char* str, int radix);
inline std::string num2str( int n )
{
char buf[10];
itoa(n,buf,10);
std::string retval = buf;
return retval;
}
template<class T> inline
void initialize(T* &arr, int sz, unsigned char val=0)
{
if( arr == NULL ) error("you should allocate memory first");
for( int i=0; i<sz; i++ )
arr[i] = val;
}
template<class T> inline
void initialize(T** &mat, int ysz, int xsz, unsigned char val=0)
{
if( mat == NULL ) error("you should allocate memory first");
for( int i=0; i<ysz; i++ )
initialize(mat[i], xsz, val);
}
template<typename T> inline
void min_max( T* data, int sz, T &mn, T &mx )
{
mn = data[0];
mx = data[0];
for( int k=1; k<sz; k++ )
{
if( mn > data[k] ) mn = data[k];
if( mx < data[k] ) mx = data[k];
}
}
template<class T> inline
T min(T* data, int sz, int &xmn)
{
T minVal=data[0];
xmn = 0;
for(int i=1; i<sz; i++ )
{
if( minVal > data[i] )
{
minVal = data[i];
xmn = i;
}
}
return minVal;
}
template<class T> inline
T min(T** data, int ysz, int xsz, int &ymn, int &xmn)
{
T minVal = data[0][0];
xmn = 0;
ymn = 0;
int minx;
T mn;
for( int y=0; y<ysz; y++ )
{
mn = min(data[y], xsz, minx);
if( mn < minVal )
{
minVal = mn;
ymn = y;
xmn = minx;
}
}
return minVal;
}
template<class T> inline
T max(T* data, int sz, int &xmx)
{
T maxVal=data[0];
xmx = 0;
for(int i=1; i<sz; i++ )
{
if( maxVal < data[i] )
{
maxVal = data[i];
xmx = i;
}
}
return maxVal;
}
template<class T> inline
T max(T** data, int ysz, int xsz, int &ymx, int &xmx)
{
T maxVal = data[0][0];
xmx = 0;
ymx = 0;
int maxx;
T mx;
for( int y=0; y<ysz; y++ )
{
mx = max(data[y], xsz, maxx);
if( mx > maxVal )
{
maxVal = mx;
ymx = y;
xmx = maxx;
}
}
return maxVal;
}
template<class T> inline
T* max( T* arr_0, T* arr_1, size_t sz, bool in_place=false )
{
T* result = NULL;
if( in_place )
result = arr_0;
else
result = allocate<T>(sz);
T* p0 = arr_0;
T* p1 = arr_1;
T* r = result;
for( int i=0; i<sz; i++ )
{
if( *p0 > *p1 ) *r = *p0;
else *r = *p1;
p0++;
p1++;
r++;
}
return result;
}
template<class T> inline
int find_interval( T number, T** list, int lsz, int equality )
{
for( int i=0; i<lsz; i++ )
{
switch(equality)
{
case 0: if( is_inside( number, list[i][0], list[i][1], 0, 0) )
return i;
break;
case 1: if( is_inside( number, list[i][0], list[i][1], 0, 1) )
return i;
break;
case 2: if( is_inside( number, list[i][0], list[i][1], 1, 0) )
return i;
break;
case 3: if( is_inside( number, list[i][0], list[i][1], 1, 1) )
return i;
break;
default:
return -1;
break;
}
}
return -1;
}
template<class T> inline
int find_interval( T nx, T ny, T** list, int lsz, int equality )
{
for( int i=0; i<lsz; i++ )
{
switch(equality)
{
case 0: if( is_inside( nx, list[i][0], list[i][1], ny, list[i][2], list[i][3], 0, 0) )
return i;
break;
case 1: if( is_inside( nx, list[i][0], list[i][1], ny, list[i][2], list[i][3], 0, 1) )
return i;
break;
case 2: if( is_inside( nx, list[i][0], list[i][1], ny, list[i][2], list[i][3], 1, 0) )
return i;
break;
case 3: if( is_inside( nx, list[i][0], list[i][1], ny, list[i][2], list[i][3], 1, 1) )
return i;
break;
default:
return -1;
break;
}
}
return -1;
}
inline bool is_digit( char c )
{
for( int i=0; i<10; i++ )
if( c == num2str(i)[0] )
return true;
return false;
}
inline bool is_number( std::string str )
{
int len=str.length();
for( int i=0; i<len; i++)
{
if( is_digit(str[i]) || str[i] == '.' || str[i] == '-' )
continue;
else
return false;
}
return true;
}
inline bool is_positive_number( std::string str )
{
if( !is_number( str ) ) return false;
float number = atof( str.c_str() );
if( number > 0.0 ) return true;
return false;
}
inline bool is_negative_number( std::string str )
{
if( !is_number( str ) ) return false;
float number = atof( str.c_str() );
if( number < 0.0 ) return true;
return false;
}
inline bool is_integer( std::string str )
{
int len=str.length();
for( int i=0; i<len; i++)
{
if( is_digit(str[i]) || str[i] == '-' )
continue;
else
return false;
}
return true;
}
inline bool is_positive_integer( std::string str )
{
if( !is_integer( str ) ) return false;
int number = atoi( str.c_str() );
if( number > 0 ) return true;
return false;
}
inline bool is_negative_integer( std::string str )
{
if( !is_integer( str ) ) return false;
int number = atoi( str.c_str() );
if( number < 0 ) return true;
return false;
}
inline void set_integer( int &location, std::string str, std::string param_name="")
{
if( !is_integer( str ) )
{
std::string errout = param_name + " should be an integer. but it is " + str;
std::cout<<errout<<std::endl;
exit(1);
}
location = atoi( str.c_str() );
}
inline void set_positive_integer( int &location, std::string str, std::string param_name="")
{
if( !is_positive_integer( str ) )
{
std::string errout;
if( param_name == "" )
errout = "parameter should be a postive integer. but it is " + str;
else
errout = param_name + " should be a postive integer. but it is " + str;
std::cout<<errout<<std::endl;
exit(1);
}
location = atoi( str.c_str() );
}
inline bool does_file_exists( std::string str )
{
std::ifstream outfile;
outfile.open(str.c_str());
if( outfile.is_open() )
{
outfile.close();
return true;
}
else
{
outfile.close();
return false;
}
}
inline bool check_file( string filename )
{
std::ifstream fin;
fin.open(filename.c_str());
if( fin.fail() ) return false;
fin.close();
return true;
}
template<typename T> inline
void create_file( string filename, long int file_size )
{
FILE* pFile = fopen( filename.c_str() , "w+" );
T* buffer = new T[file_size];
fwrite(buffer , sizeof(T) , file_size , pFile );
delete []buffer;
fclose(pFile);
}
#if !defined(WIN32)
#ifdef HAVE_LARGE_FILE_SUPPORT
#define mmap mmap64
#define open open64
#endif
template<typename T> inline
void map_memory_file(string memory_file, long int size, T* &mapped_file)
{
int fildes = open(memory_file.c_str(), O_RDWR);
if(fildes == -1) {
create_file<T>(memory_file,size);
fildes = open(memory_file.c_str(), O_RDWR);
}
void* file = mmap(0, size*sizeof(T), PROT_READ|PROT_WRITE, MAP_SHARED, fildes, 0);
if(file == MAP_FAILED)
{
error("file cannot be mapped");
}
mapped_file = (T*)file;
}
#endif
inline string get_file_format( string file )
{
size_t found = file.find_last_of(".");
string file_format = file.substr(found+1);
return file_format;
}
inline string get_file_name( string file )
{
size_t found = file.find_last_of("/\\");
string file_name = file.substr(found+1);
return file_name;
}
inline string get_folder_name( string file )
{
size_t found = file.find_last_of("/\\");
string folder_name = file.substr(0,found);
return folder_name;
}
inline string get_file_root( string file )
{
string file_name = get_file_name(file);
size_t found = file_name.find_last_of(".");
string file_root = file_name.substr(0,found);
return file_root;
}
}
#endif