#include <iostream>
#include "_error.hpp"
int main()
{
}
/** Массивы
* Библиотека OWNI */
#pragma once
#define FILE_array
#include "_types.hpp"
/** Итератор */
class Iterator {
protected:
INT_L sz=0;// размер
INT_L idx=0;// индекс
LOGIC how=false;// признак перебора
public:
/** Получение признака перебора */
LOGIC How(){return how;}
/** Указание как перебирать
* @param how `true` с конца, `false` с начала */
void How(LOGIC how){Index(how?-1:0);this->how=how;}
/** Размер */
INT_L Size(){return sz;}
/** Текущий индекс */
INT_L Index(){return sz?idx+1:0;}
/** Установка индекса
* @param idx новый интдекс */
void Index(INT_L idx){z::Index(idx,sz);this->idx=idx;}
/** Сброс
* @param idx индекс */
void Reset(INT_L idx=0){
Index(idx?idx:this->how?-1:0);
}
/** Проверка на последний элемент */
LOGIC Last(){
LOGIC res=false;
if(this->how){
if(idx==0)res=true;
}else{
if(idx==sz-1)res=true;
}
return res;
}
/** Переход к следующему элементу */
LOGIC Next(){
LOGIC res=false;
if(this->how){
if(idx>0){idx--;res=true;}
}else{
if(idx<sz-1){idx++;res=true;}
}
return res;
}
};
/** Массив */
template <typename dTYPE>
class Array :public Iterator {
INT_W rv=0;
INT_L tl=0;
dTYPE *vars=NULL;
void Init(INT_L tl,INT_W rv){
if(vars)delete []vars;
if(tl){
if(rv)tl=z::Volume(tl,rv);
vars=new dTYPE[tl];
}else vars=NULL;
this->tl=tl;this->rv=rv;idx=sz=0;how=false;
}
public:
Array(INT_L tl=0,INT_W rv=10){this->Init(tl,rv);}
Array(const Array &obj){
this->Init(obj.sz,0);sz=obj.sz;
if(sz){
ADDRESS adr1=vars,adr2=obj.vars;
z::Copy(adr1,adr2,sz*sizeof(dTYPE));
}
}
~Array(){if(vars)delete []vars;}
operator bool(){return sz?true:false;}
dTYPE& operator[](INT_L idx){
if(idx==0)idx=this->idx;
else z::Index(idx,sz);
return vars[idx];
}
Array<dTYPE>& operator=(Array<dTYPE> &oar){
if(this!=&oar){
if(tl<oar.sz)this->Init(oar.tl,rv);
if(oar.sz){sz=oar.sz;
ADDRESS adr1=vars,adr2=oar.vars;
z::Copy(adr1,adr2,sz*sizeof(dTYPE));
}
}
return *this;
}
/** Очистка массива */
void Clear(){this->Init(0,0);}
/** Тотальный размер в памяти */
INT_L Total(){return tl;}
/** Размер резервирования */
INT_L Reserve(){return rv;}
/** Установка размера резервирования
* @param rv размер резервирования */
void Reserve(INT_W rv){this->rv=rv;}
/** Добавление новых элементов массива
* @param ...args новые элементы */
template<typename... aARG>
void Add(aARG ...args){
(this->Put(args), ...);
}
/** Положить новый элемент
* @param val значение
* @param idx индекс */
void Put(dTYPE val,INT_L idx=0){
if(sz<4294967295){
INT_L nsz=sz+1;
INT_L ntl=rv?z::Volume(nsz,rv):tl;
if(nsz<ntl){
if(idx)z::Index(idx,nsz);else idx=sz;
if(tl!=ntl){tl=ntl;
dTYPE *nvrs=new dTYPE[tl];
if(vars){
INT_S ln=sizeof(dTYPE);
ADDRESS adr1=nvrs,adr2=vars;
z::Copy(adr1,adr2,idx*ln);
if(idx<sz){z::Shift(adr1,ln);
z::Copy(adr1,adr2,(nsz-idx)*ln);
}
delete []vars;
}
vars=nvrs;
}else if(idx<sz){
INT_S ln=sizeof(dTYPE);
ADDRESS adr1,adr2=vars;
z::Shift(adr2,sz*ln);adr1=adr2;
z::Shift(adr2,-ln);
z::Copy(adr1,adr2,-(sz-idx)*ln);
}
vars[idx]=val;sz++;
}
}
}
/** Взять значение элемента
* @param idx индекс */
dTYPE Take(INT_L idx=-1){
dTYPE val;
if(sz){
z::Index(idx,sz);val=vars[idx];
if(idx<sz){
INT_S ln=sizeof(dTYPE);
ADDRESS adr1,adr2=vars;
z::Shift(adr2,idx*ln);adr1=adr2;
z::Shift(adr2,ln);
z::Copy(adr1,adr2,(sz-idx)*ln);
}
sz--;
}else val=0;
return val;
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<< (std::ostream &out,Array<dTYPE> &oar){
INT_L sz=oar.Size();
out<<std::endl;
if(sz){out<<'{'<<std::endl;
INT_L ix=oar.Index();
for(INT_L nx=0;nx++<sz;){i::tab(1);
out<<'['<<nx<<']'<<(ix==nx?'>':' ')<<oar[nx]<<std::endl;
}
out<<'}';
}else out<<"NULL";
return out<<std::endl;
}
#endif
};
ID_TYPE(31,Array<LOGIC>)
ID_TYPE(32,Array<CHAR>)
ID_TYPE(33,Array<RANGE>)
ID_TYPE(34,Array<BYTE>)
ID_TYPE(35,Array<INT_S>)
ID_TYPE(36,Array<INT_W>)
ID_TYPE(37,Array<INT_M>)
ID_TYPE(38,Array<INT_L>)
ID_TYPE(39,Array<INT_T>)
ID_TYPE(40,Array<INT_B>)
ID_TYPE(41,Array<FLOAT>)
ID_TYPE(42,Array<DOUBLE>)
ID_TYPE(43,Array<ADDRESS>)
ID_TYPE(44,Array<CHARS>)
ID_TYPE(45,Array<STRING>)
ID_TYPE(46,Array<DATETIME>)
/** Аргументы */
class Args :public Array<ADDRESS> {
public:
Args(){}
template<typename... aARG>
Args(aARG... args){(Put(args), ...);}
~Args(){Clear();}
ANY& operator[](INT_L idx){
if(!Size())Array<ADDRESS>::Put(new ANY);
return *(ANY*)Array<ADDRESS>::operator[](idx);
}
/** Очистка аргументов */
void Clear(){
if(Size()){Reset();
do{
delete static_cast<ANY*>(Array<ADDRESS>::operator[](0));
}while(Next());
Array<ADDRESS>::Clear();
}
}
/** Положить новый элемент
* @param val значение
* @param idx индекс */
template <typename dTYPE>
void Put(dTYPE val,INT_L idx=0){
Array<ADDRESS>::Put(new ANY(val),idx);
}
/** Взять значение элемента
* @param idx индекс */
ANY Take(INT_L idx=-1){
ANY res;
if(Size()){
ADDRESS pnt=Array<ADDRESS>::Take(idx);
res=*(ANY*)pnt;delete static_cast<ANY*>(pnt);
}
return res;
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<<(std::ostream &out,Args &oar){
INT_L sz=oar.Size();
out<<std::endl;
if(sz){out<<'{'<<std::endl;
INT_L ix=oar.Index();
for(INT_L nx=0;nx++<sz;){i::tab(1);
out<<'['<<nx<<']'<<(ix==nx?'>':' ')<<oar[nx]<<std::endl;
}
out<<'}';
}else out<<"NULL";
return out<<std::endl;
}
#endif
};
ID_TYPE(47,Args)
/*
namespace a {
template<typename dTYPE>
INT_L Find(Array<dTYPE> obj,const dTYPE val){
INT_L res=0,idx=obj.Index();
if(obj.Size()){obj.Reset();
do{
if(obj[0]==val){res=obj.Index();break;}
}while(obj.Next());
obj.Index(idx);
}
return res;
}
}
*/
/** Ассоциативный массив */
class Associative :public Array<ADDRESS> {
/** Структура КлючЗначение */
struct KeyValue {
STRING key;// ключ
ANY value;// значение
};
void Add()=delete;
KeyValue* SKV(INT_L idx){
return (KeyValue*)Array<ADDRESS>::operator[](idx);
}
KeyValue* SKV(STRING key){
KeyValue *skv;
INT_L fid=Find(key);
if(fid)skv=(KeyValue*)Array<ADDRESS>::operator[](fid);
else{
skv=new KeyValue;skv->key=key;
Array<ADDRESS>::Put(skv);
}
return skv;
}
public:
Associative(){}
//Associative(const Associative &obj): apr(obj.apr),dbl(true){}
~Associative(){Clear();}
ANY& operator[](CHARS key){
return SKV(key)->value;
}
ANY& operator[](STRING key){
return SKV(key)->value;
}
/** Очистка массива */
void Clear(){
if(sz){Reset();
do{
delete static_cast<KeyValue*>(Array<ADDRESS>::operator[](0));
}while(Next());
Array<ADDRESS>::Clear();
}
}
/** Положить новый элемент
* @param key ключ
* @param val значение
* @param idx индекс */
void Put(STRING key,ANY val,INT_L idx=-1){
KeyValue *skv=SKV(key);
skv->key=key;skv->value=val;
//Array<ADDRESS>::Put(skv,idx);
}
/** Получение ключа
* @param idx индекс */
STRING Key(INT_L idx=0){
STRING key;
if(sz)key=((KeyValue*)Array<ADDRESS>::operator[](idx))->key;
return key;
}
/** Получение значения
* @param idx индекс */
ANY Value(INT_L idx=0){
ANY val;
if(sz)val=((KeyValue*)Array<ADDRESS>::operator[](idx))->value;
return val;
}
/** Взять значение элемента
* @param key ключ
* @return значение */
ANY Take(STRING key){
ANY val;
INT_L fid=Find(key);
if(fid){
ADDRESS pnt=Array<ADDRESS>::Take(fid);
val=((KeyValue*)pnt)->value;
delete static_cast<KeyValue*>(pnt);
}
return val;
}
INT_L Find(STRING key,INT_L idx=0){
INT_L res=0;
if(sz){
INT_L tix=Index();Reset(idx);
do{
if(key==Key()){res=Index();break;}
}while(Next());
Index(tix);
}
return res;
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<<(std::ostream &out,Associative &oas){
INT_L sz=oas.Size();
out<<std::endl;
if(sz){out<<'{'<<std::endl;
INT_W ltb=0;
for(INT_L nx=0;nx++<sz;){
INT_W ksz=oas.Key(nx).Size();
if(ltb<ksz)ltb=ksz;
}
ltb++;
KeyValue *kv;
INT_L ix=oas.Index();
for(INT_L nx=0;nx++<sz;){
i::tab(1);kv=oas.SKV(nx);
out<<'['<<nx<<']'<<(ix==nx?'>':' ');
i::w(ltb);i::l();
out<<kv->key<<'='<<kv->value<<std::endl;
}
out<<'}';
}else out<<"NULL";
return out<<std::endl;
}
#endif
};
ID_TYPE(48,Associative)
/*
#ifdef FILE_zests
namespace a {
template <typename dTYPE>
void v(const Array<dTYPE> &oar){
Array<dTYPE> obj(oar);
INT_W rv=obj.Reserve();INT_L sz=obj.Size();
t::tab();
std::cout<<"Array<"<<::Type<dTYPE>::Name<<">("<<sz;
if(rv)std::cout<<','<<obj.Total()<<','<<rv;
std::cout<<"){";
if(sz){std::cout<<std::endl;
INT_L ix=obj.Index();
for(INT_L nx=0;nx++<sz;){
t::tab(1);
std::cout<<'['<<nx<<']'<<(ix==nx?'>':' ');
t::v(obj[nx]);std::cout<<std::endl;
}
}
std::cout <<'}';
}
}
#endif
*/
/** Базовые классы
* Библиотека OWNI */
#pragma once
#define FILE_base
#include "_types.hpp"
/** АвтоУказатель */
template<typename dTYPE>
class AutoPOINTER{
LOGIC sgn=true;
static dTYPE *pnt;
public:
~AutoPOINTER(){if(sgn)this->Clear();}
AutoPOINTER(AutoPOINTER &obj){sgn=false;}
AutoPOINTER(){AutoPOINTER::pnt=new (dTYPE);}
AutoPOINTER(dTYPE val){AutoPOINTER::pnt=new (dTYPE)(val);}
AutoPOINTER(dTYPE val){AutoPOINTER::pnt=new (dTYPE)(val);}
dTYPE& operator *(){return *(dTYPE*)pnt;}
explicit operator bool(){return AutoPOINTER::pnt?true:false;}
void Clear(){
if(AutoPOINTER::pnt){
delete AutoPOINTER::pnt;AutoPOINTER::pnt=NULL;
}
}
};
template<class oCLASS>
oCLASS* AutoPOINTER<oCLASS>::pnt=NULL;
/*
#ifdef VAR
#if VAR+0<1
тут код, VAR заменить на CLASS_Название
#undef VAR
#define VAR 1
#endif
#endif
*/
/*
/ *
STRING tostr(INT_W num){
LETTER *lts=new LETTER[20];
_itoa(num,lts,10);
return STRING(lts);
}
STRING ClassType(STRING type){
INT_W len=type.Size()-1;
type-=tostr(len);
return type;
}
STRING ClassType(STRING type){
INT_W len=type.Size()-1;
LETTER *lts=new LETTER[20];
_itoa(len,lts,10);type-=lts;
return type;
}
*/
/** Вычисление\преобразование
* Библиотека OWNI */
#pragma once
#define FILE_calc
#include "_types.hpp"
namespace c {
template <typename dTYPE>
dTYPE d10(dTYPE var){
BYTE num=BYTE(var%10);
while(num==0){var=var/10;num=var%10;}
return var;
}
/** Получение абсолютного значения
* @param var переменная
* @return абсолютное значение */
template <typename dTYPE>
dTYPE absolute(dTYPE var){
if(var<0)var=-var;
return var;
}
/** Получение целого числа
* @param var переменная FLOAT
* @return целое число INT_L */
INT_L integer(FLOAT var){
return INT_L(var);
}
/** Получение целого числа
* @param var переменная DOUBLE
* @return целое число INT_B */
INT_B integer(DOUBLE var){
return INT_B(var);
}
/** Дробная часть
* @param var переменная FLOAT
* @return значение FLOAT */
FLOAT fraction(FLOAT var){
var-=INT_L(var);
return var;
}
/** Дробная часть
* @param var переменная DOUBLE
* @return значение DOUBLE */
DOUBLE fraction(DOUBLE var){
var-=INT_L(var);
return var;
}
/** Целая часть
* @param var переменная FLOAT
* @return значение INT_L */
INT_L whole(FLOAT var){
var-=integer(var);
INT_L res=var*1000;
return d10(res);
}
/** Целая часть
* @param var переменная DOUBLE
* @return значение INT_B */
INT_B whole(DOUBLE var){
var-=integer(var);
INT_B res=var*1000000;
return d10(res);
}
/*
* Получение шестнадтиричного значения байта
* @param b байт
* @return HEX значение * /
STRING Hex(BYTE b,LOGIC sg=false){
STRING st(16);
st="0123456789";st+=sg?"ABCDEF":"abcdef";
LETTER hx[3]={st[1+b/16],st[1+b%16],'\0'};
return STRING(hx);
}*/
}
/** Работа с диском
* Библиотека OWNI */
#pragma once
#define FILE_disc
//#include <filesystem>
#include "_array.hpp"
#include <iostream>
using namespace std;
namespace d{
#include <windows.h>
/** Диск информация */
class Disc :public Array<ADDRESS> {
/* * Структура ДискИнформация * /
struct DiscInfo{
STRING drive;// драйв\\диск
STRING label;// метка диска
STRING type;// тип файловой системы
INT_B size;// общий размер
INT_B free;// свободное место
};*/
public:
Disc(){
//WCHAR lpBuffer[MAX_PATH];
//DWORD dwSize = MAX_PATH;cout<<*buf;
WCHAR dbuf[104];
if(GetLogicalDriveStringsW(MAX_PATH,dbuf)){
WCHAR *drv=dbuf;
while(*drv){
BYTE dtp=GetDriveTypeW(drv);
Associative *disc=new Associative;
switch(dtp){
case 1: (*disc)["type"]="NO_ROOT";break;
case 2: (*disc)["type"]="REMOVABLE";break;
case 3: (*disc)["type"]="FIXED";break;
case 4: (*disc)["type"]="REMOTE";break;
case 5: (*disc)["type"]="CDROM";break;
case 6: (*disc)["type"]="RAMDISC";break;
default: (*disc)["type"]="UNKNOWN";
}
cout<<*disc<<endl;
if(dtp){
WCHAR lbuf[MAX_PATH];CHAR xx;
ADDRESS adr=&lbuf;z::Fill(adr,MAX_PATH);
if(GetVolumeInformationW(drv,lbuf,MAX_PATH,NULL,NULL,NULL,NULL,0)){
STRING st(L"проверка");//*drv
wcout << "Drive: " << st << endl;
wcout << "Volume label: " <<lbuf<<endl;
}else{
wcout << "GetVolumeInformationW failed with error code: " << GetLastError() << endl;
}
}
drv+= wcslen(drv) + 1;
}
}
/*
std::cout << "GetLogicalDriveStringsW failed with error code: " << GetLastError() << std::endl;
*/
}
};
}
/*
namespace d {
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
class Info {
private:
STRING way;
struct stat status;
public:
Info(STRING way){
this->way=way;
stat(*way, &this->status);
}
STRING Mode(){
STRING res;
switch (this->status.st_mode & S_IFMT){
case S_IFREG: res="file";break;
case S_IFIFO: res="fifo";break;
case S_IFDIR: res="folder";break;
case S_IFBLK: res="block device";break;
case S_IFCHR: res="character device";break;
//case S_IFLNK: res="symbolic link";break;
//case S_IFSOCK: res="socket";break;
default: res="unknown";
}
return res;
}
STRING Way(){return this->way;}
INT_S Uid(){return this->status.st_uid;}
INT_S Gid(){return this->status.st_gid;}
INT_W Ino(){return this->status.st_ino;}
INT_L Dev(){return this->status.st_dev;}
INT_B Size(){return this->status.st_size;}
INT_L Rdev(){return this->status.st_rdev;}
INT_S Nlink(){return this->status.st_nlink;}
DATETIME Opening(){return DATETIME(this->status.st_atime);}
DATETIME Creating(){return DATETIME(this->status.st_ctime);}
DATETIME Modification(){return DATETIME(this->status.st_mtime);}
};
Associative scan(CHARS(pth)){
Associative res;
struct dirent *dt;
DIR *dir=opendir(pth);
if(dir!=NULL){
Array<STRING> way;
Associative *fls=new Associative;
Array<STRING> *fld=new Array<STRING>;
way.Put(pth);way.Put("");
while((dt=readdir(dir))!=NULL){
way[2]=dt->d_name;
Info inf(s::text(way));
STRING mode=inf.Mode();
if(way[2]!="." && way[2]!=".."){
if(mode=="folder")(*fld).Put(way[2]);
else if(mode=="file"){
Associative *ifl=new Associative;
(*ifl)["size"]=inf.Size();
(*ifl)["opening"]=inf.Opening();
(*ifl)["creating"]=inf.Creating();
(*ifl)["modification"]=inf.Modification();
(*fls)[way[2]]=*ifl;
}
}
}
if(*fld)res["folders"]=*fld;
if(*fls)res["files"]=*fls;
closedir(dir);
}
return res;
}
}*/
/** Обработка ошибок
* Библиотека OWNI */
#pragma once
#define FILE_error
//#include <exception>
#include <iostream>
#include "_quasi.hpp"
/** Класс ошибки */
class Error {
bool exi;
const TCHAR *msg;
public:
static const char *func;
static const char *file;
static unsigned int line;
/** Конструктор
* @param msg сообщение
* @param exi признак продолжения */
Error(const TCHAR *msg,bool exi=false):msg(msg),exi(exi){}
/** Вывод информации о ошибке */
void info(){
std::cout<<std::endl<<file<<' '<<func<<':'<<line<<' ';
_COUT<<msg;
if(exi)exit(1);
}
/** Вывод информации о исключении */
static void exce(const char* tpe,const char* msg){
std::cout<<std::endl<<file<<' '<<func<<':'<<line<<' '<<tpe<<' '<<msg;
}
};
const char* Error::func=__FUNCTION__;
const char* Error::file=__FILE__;
unsigned int Error::line=__LINE__;
#define FIX Error::func=__FUNCTION__;Error::file=__FILE__;Error::line=__LINE__;
#define TRY try{
#define CATCH }catch(Error err){err.info();}\
catch(const exception &exc){Error::exce(typeid(exc).name(),exc.what());}
/** Интерфэйс
* Библиотека OWNI */
#pragma once
#define FILE_interface
#include <clocale>
#include <iomanip>
#include <fcntl.h>
#include <iostream>
#include "_calc.hpp"
/** Пространство имёт от _interface */
namespace i {
using namespace std;
/** число символов сдвига табуляции */
INT_W tab=0;
/** Табуляция
* @param tb число символов табуляции
* @param sl символ табуляции */
void t(INT_W tb=2){
BYTE tsz=tab+tb;
_COUT<<setfill(_L(' '))<<setw(tsz)<<_L(' ');
}
/** Символ заполнения */
void f(const CHAR chr){
cout<<setfill(chr);
}
/** Символ заполнения */
void f(const WCHAR chr){
wcout<<setfill(chr);
}
/** Флаг вывода с лево */
void l(){
_COUT<<setiosflags(ios::left);
}
/** Флаг вывода с право */
void r(){
_COUT<<setiosflags(ios::right);
}
/** Ширина вывода
* @param wh количество символов */
void w(BYTE wh){
_COUT<<setw(wh);
}
/** Ввод значения */
template <typename dTYPE>
void i(dTYPE &var){
cin>>var;
}
/* * Ввод значения с сообщением * /
template <typename dTYPE>
void i(STRING msg,dTYPE &var){
cout<<endl<<msg<<": ";cin>>var;
}
/ ** Вывод типа и значения
* @param var переменная
* @param cmt комментарий * /
template <typename dTYPE>
void o(const dTYPE &var,STRING cmt=""){
ANY any(var);
cout<<endl;tab();
cout<<any.Type()<<'{'<<any<<'}';
if(cmt)cout<<' '<<cmt;
}
/ ** Вывод строки с параметрами
* @param str строка
* @param cmt комментарий * /
void o(STRING &str,STRING cmt=""){
INT_W rv=str.Reserve();
cout<<endl;tab();
cout<<"STRING("<<str.Size()<<','<<str.Total();
if(rv)cout<<','<<rv;
cout<<"){"<<str<<'}';
if(cmt)cout<<' '<<cmt;
}
/ ** Вывод любого типа
* @param any любой тип
* @param cmt комментарий * /
void o(ANY &any,STRING cmt=""){
cout<<endl;tab();
cout<<"ANY{"<<any.Type()<<'{'<<any<<"}}";
if(cmt)cout<<' '<<cmt;
}*/
/** Вывод параметров */
template<typename... aARG>
void p(aARG... args){(o(args), ...);}
/*
void dump(POINTER pnt,INT_W size){
cout<<endl<<"#address\t0 1 2 3 4 5 6 7\t\t~~dump~~"<<endl;
i::tab(56,'-');cout<<endl<<hex;
BYTE val,col=0;
STRING txt(" ");
while(size>0){
val=*(BYTE*)pnt;
if(col==0){cout<<pnt<<'\t';col=0;}
else cout<<' ';
cout<<c::Hex(val);
col++;if(val>15)txt[col]=val;
if(col==8){
cout<<"\t\t"<<txt<<endl;
txt=" ";col=0;
}
z::Shift(pnt);size--;
}
if(col){
if(col<6)cout<<'\t';
if(col<3)cout<<'\t';
cout<<"\t\t"<<txt<<endl;
}
i::tab(56,'-');cout<<dec<<endl;
}
template <typename dTYPE>
void dump(const dTYPE &var){
cout<<endl<<"# "<<::Type<dTYPE>::Name;
dump((POINTER)&var,sizeof(var));
}
void dump(CHAR *ltr){
INT_W sz=z::Lsize(ltr);
cout<<endl<<"# "<<(sz>1?"CHARS":"CHAR");
dump((POINTER)ltr,sz);
}
void dump(CHARS(ltr)){
dump((CHAR*)ltr);
}
void dump(const STRING &str,STRING msg=""){
cout<<endl<<"# STRING";
if(msg)cout<<"\t"<<msg;
STRING obj(str);
dump((POINTER)*obj,obj.Total());
}*/
/** Включение кирилицы */
void c(){
setlocale (LC_ALL,"");
#ifdef UNICODE
_setmode(_fileno(stdin),_O_U8TEXT);
_setmode(_fileno(stdout),_O_U8TEXT);
_setmode(_fileno(stderr),_O_U8TEXT);
#endif
}
/** Остановка */
void s(){
_COUT<<endl;system("pause");
}
}
/** Квази шаблоны
* Библиотека OWNI */
#pragma once
#define FILE_quasi
#ifdef UNICODE
typedef wchar_t TCHAR;// Универсальный символьный тип
#define _COUT std::wcout// универсальный вывод
#define _L(c) L##c// универсальный символьный массив
#else
typedef char TCHAR;// Универсальный символьный тип
#define _COUT std::cout // универсальный вывод
#define _L(c) c // универсальный символьный массив
#endif
/** Типы данных
* Библиотека OWNI */
#pragma once
#define FILE_types
//#include <typeinfo>
//#include <cstdlib>
//#include <stdio.h>
#include <ctime>
#include "_quasi.hpp"
typedef bool LOGIC;// Логический тип 0..1
typedef char CHAR;// Буква
typedef __INT8_TYPE__ RANGE;// Диапазон -128..127
typedef __UINT8_TYPE__ BYTE;// Байт 0..255
typedef __INT16_TYPE__ INT_S;// Целое число -32768..32767
typedef __UINT16_TYPE__ INT_W;// Целое число 0..65535
typedef wchar_t WCHAR;// Буква Юникода
typedef __INT32_TYPE__ INT_M;// Целое число -2147483648..2147483647
typedef __UINT32_TYPE__ INT_L;// Целое число 0..4294967295
typedef __INT64_TYPE__ INT_T;// Целое число -9223372036854775808..9223372036854775807
typedef __UINT64_TYPE__ INT_B;// Целое число 0..18446744073709551615
typedef float FLOAT;// Плавающее число 1.8E-38..1.8E+38 32b точность 6 .3 знаков
typedef double DOUBLE;// Плавающее число двойной точности 2.2E-308..1.8E+308 64b точность 15 .6 знаков
typedef void* ADDRESS;// Указатель адреса
/** Нулевой указатель */
#ifndef NULL
#define NULL ((void *)0)
#endif
/** Пустые макросы _error */
#ifndef FILE_error
#define FIX
#define TRY
#define CATCH
#endif
/** Структура типа Id и Name */
template<typename dTYPE> struct Type {
/** Id типа */
static const INT_W Id=0;
/** Name типа */
static constexpr char Name[]="UNKNOWN";
};
/** Добавление ID типа */
#define ID_TYPE(nID,dTYPE) \
template<> struct Type<dTYPE> {\
static const INT_W Id=nID;\
static constexpr char Name[]=#dTYPE;\
};
ID_TYPE(1,LOGIC)
ID_TYPE(2,CHAR)
ID_TYPE(3,RANGE)
ID_TYPE(4,BYTE)
ID_TYPE(5,INT_S)
ID_TYPE(6,INT_W)
ID_TYPE(7,WCHAR)
ID_TYPE(8,INT_M)
ID_TYPE(9,INT_L)
ID_TYPE(10,INT_T)
ID_TYPE(11,INT_B)
ID_TYPE(12,FLOAT)
ID_TYPE(13,DOUBLE)
ID_TYPE(14,ADDRESS)
/** Структура битов .b0..b7 */
struct Bits {
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
};
/** Структура байтов .b0..b7 */
struct Bytes {
BYTE b0;
BYTE b1;
BYTE b2;
BYTE b3;
BYTE b4;
BYTE b5;
BYTE b6;
BYTE b7;
};
/** Союз BYTE & Bits */
union Code {
BYTE byte;
Bits bit;
};
/** Союз INT_B & Bytes */
union Block {
INT_B numb;
Bytes byte;
};
/** Структура даты-времени */
struct DateTime {
int seconds;
int minutes;
int hours;
int day;
int month;
int year;
int wday;
int yday;
int summer;
};
/** Союз tm & DateTime */
union DateTimeU {
struct tm stm;
DateTime dtm;
};
/** Пространство имёт от _types */
namespace t {
/** Проверка на тип\класс */
template <bool tBool, class oCLASS=void>
struct IfType {};
template <class oCLASS>
struct IfType<true, oCLASS> {typedef oCLASS type;};
/** Включение в компиляцию */
template <bool tBool, class oCLASS=void>
using Enable = typename IfType<tBool,oCLASS>::type;
/** Сравнение типов */
template <typename T1,typename T2>
struct Match {static const bool v=false;};
template <typename T0>
struct Match<T0,T0> {static const bool v=true;};
/** Ниличие типа в перечне */
template <typename dTYPE, typename ...aTYPE>
struct IsMatch{static constexpr bool v{(Match<dTYPE,aTYPE>::v || ...)};};
/** Проверка на базовый тип данных */
template <typename dTYPE>
constexpr bool isBaseB=IsMatch<dTYPE,LOGIC,CHAR,RANGE,BYTE,INT_S,INT_W,INT_M,INT_L,INT_T,INT_B,FLOAT,DOUBLE,ADDRESS>::v;
/** Проверка на целочисленный тип данных */
template <typename dTYPE>
constexpr bool isInteger=IsMatch<dTYPE,RANGE,BYTE,INT_S,INT_W,INT_M,INT_L,INT_T,INT_B>::v;
/** Проверка на дробный тип данных */
template <typename dTYPE>
constexpr bool isFloating=IsMatch<dTYPE,FLOAT,DOUBLE>::v;
};
#include "_zests.hpp"
/** Указатель */
template<typename dTYPE>
class POINTER {
dTYPE *pnt;
POINTER *obj=NULL;
void Kill(LOGIC grd){
if(obj)obj->Kill(grd);else if(!grd)delete pnt;
pnt=NULL;
}
public:
/** защита от уничтожения */
LOGIC guard=false;
POINTER(){pnt=new dTYPE;}
POINTER(dTYPE val){pnt=new dTYPE(val);}
POINTER(POINTER &obj):pnt(obj.pnt),obj(&obj){
if(obj.guard)obj.guard=false;
}
~POINTER(){if(!obj)if(pnt)delete pnt;}
explicit operator bool(){return pnt?true:false;}
dTYPE& operator*(){return *(dTYPE*)pnt;}
dTYPE& operator=(dTYPE val){
if(pnt)*(dTYPE*)pnt=val;
return *this;
}
/** Уничтожение указателя */
void Kill(){
if(obj)obj->Kill(guard);else delete pnt;
if(!guard)pnt=NULL;
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<< (std::ostream &out,const POINTER &obj){
return obj.pnt?out<<*(dTYPE*)obj.pnt:out<<"NULL";
}
#endif
};
/** Указатель */
template<>
class POINTER<CHAR> {
void Kill(LOGIC grd){
if(obj)obj->Kill(grd);else if(!grd)delete pnt;
pnt=NULL;sz=tl=rv=0;
}
protected:
CHAR *pnt;
INT_W sz=0,tl,rv;
POINTER<CHAR> *obj=NULL;
CHAR* Change(){
CHAR *lts=NULL;
if(rv){INT_W ntl=z::Volume(sz,rv);
if(tl!=ntl){tl=ntl;lts=new CHAR[INT_L(tl+1)];}
}
return lts;
}
void Assign(const CHAR *pch){
ADDRESS adr=pnt;
if(sz){
ADDRESS adl=(ADDRESS)pch;
z::Copy(adr,adl,sz*sizeof(CHAR));
}
*(CHAR*)adr=0;
}
public:
/** защита от уничтожения */
LOGIC guard=false;
POINTER<CHAR>(INT_W tl=32,INT_W rv=0):tl(tl),rv(!tl && !rv?32:rv){
pnt=new CHAR[tl+1];*(CHAR*)pnt=0;
}
POINTER<CHAR>(const CHAR *pch){
sz=tl=z::Lsize(pch);rv=0;
pnt=new CHAR[tl+1];Assign(pch);
}
POINTER<CHAR>(POINTER<CHAR> &obj):
pnt(obj.pnt),sz(obj.sz),tl(obj.tl),obj(&obj){
if(obj.guard)obj.guard=false;
}
~POINTER<CHAR>(){if(!obj)if(pnt)delete pnt;}
explicit operator bool(){return pnt?true:false;}
CHAR* operator*(){return pnt;}
POINTER<CHAR>& operator=(const CHAR *pch){
if(pnt){
sz=z::Lsize(pch);
if(CHAR *npt=Change()){
delete []pnt;pnt=npt;
}else if(sz>tl)sz=tl;
Assign(pch);
}
return *this;
}
/** Уничтожение указателя */
void Kill(){
if(pnt){
if(obj)obj->Kill(guard);else delete pnt;
if(!guard){pnt=NULL;sz=tl=rv=0;}
}
}
/** Получение\подсчёт размера массива символов
* @param sgn `true` для подсчёта
* @return количество символов */
INT_W Size(LOGIC sgn=false){
if(sgn)sz=z::Lsize(pnt);
return sz;
}
/** Тотальный размер в памяти */
INT_W Total(){return tl;}
/** Размер резервирования */
INT_W Reserve(){return rv;}
/** Установка размера резервирования */
void Reserve(INT_W rv){this->rv=rv;}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<< (std::ostream &out,const POINTER<CHAR> &obj){
return obj.sz?out<<(CHAR*)obj.pnt:out<<"NULL";
}
#endif
};
/** Указатель */
template<>
class POINTER<WCHAR> {
void Kill(LOGIC grd){
if(obj)obj->Kill(grd);else if(!grd)delete pnt;
pnt=NULL;sz=tl=rv=0;
}
protected:
WCHAR *pnt;
INT_W sz=0,tl,rv;
POINTER<WCHAR> *obj=NULL;
WCHAR* Change(){
WCHAR *lts=NULL;
if(rv){INT_W ntl=z::Volume(sz,rv);
if(tl!=ntl){tl=ntl;lts=new WCHAR[INT_L(tl+1)];}
}
return lts;
}
void Assign(const WCHAR *pch){
ADDRESS adr=pnt;
if(sz){
ADDRESS adl=(ADDRESS)pch;
z::Copy(adr,adl,sz*sizeof(WCHAR));
}
*(WCHAR*)adr=0;
}
public:
/** защита от уничтожения */
LOGIC guard=false;
POINTER<WCHAR>(INT_W tl=64,INT_W rv=0):tl(tl),rv(!tl && !rv?64:rv){
pnt=new WCHAR[tl+1];*(WCHAR*)pnt=0;
}
POINTER<WCHAR>(const WCHAR *pch){
sz=tl=z::Lsize(pch);rv=0;
pnt=new WCHAR[tl+1];Assign(pch);
}
POINTER<WCHAR>(POINTER<WCHAR> &obj):
pnt(obj.pnt),sz(obj.sz),tl(obj.tl),obj(&obj){
if(obj.guard)obj.guard=false;
}
~POINTER<WCHAR>(){if(!obj)if(pnt)delete pnt;}
explicit operator bool(){return pnt?true:false;}
WCHAR* operator*(){return pnt;}
POINTER<WCHAR>& operator=(const WCHAR *pch){
if(pnt){
sz=z::Lsize(pch);
if(WCHAR *npt=Change()){
delete []pnt;pnt=npt;
}else if(sz>tl)sz=tl;
Assign(pch);
}
return *this;
}
/** Уничтожение указателя */
void Kill(){
if(pnt){
if(obj)obj->Kill(guard);else delete pnt;
if(!guard){pnt=NULL;sz=tl=rv=0;}
}
}
/** Получение\подсчёт размера массива символов
* @param sgn `true` для подсчёта
* @return количество символов */
INT_W Size(LOGIC sgn=false){
if(sgn)sz=z::Lsize(pnt);
return sz;
}
/** Тотальный размер в памяти */
INT_W Total(){return tl;}
/** Размер резервирования */
INT_W Reserve(){return rv;}
/** Установка размера резервирования */
void Reserve(INT_W rv){this->rv=rv;}
#ifdef _GLIBCXX_IOSTREAM
friend std::wostream& operator<< (std::wostream &out,const POINTER<WCHAR> &obj){
return obj.sz?out<<(WCHAR*)obj.pnt:out<<"NULL";
}
#endif
};
ID_TYPE(21,POINTER<LOGIC>)
ID_TYPE(22,POINTER<CHAR>)
ID_TYPE(23,POINTER<RANGE>)
ID_TYPE(24,POINTER<BYTE>)
ID_TYPE(25,POINTER<INT_S>)
ID_TYPE(26,POINTER<INT_W>)
ID_TYPE(27,POINTER<WCHAR>)
ID_TYPE(28,POINTER<INT_M>)
ID_TYPE(29,POINTER<INT_L>)
ID_TYPE(30,POINTER<INT_T>)
ID_TYPE(31,POINTER<INT_B>)
ID_TYPE(32,POINTER<FLOAT>)
ID_TYPE(33,POINTER<DOUBLE>)
ID_TYPE(34,POINTER<ADDRESS>)
/** Строка */
class STRING {
enum STYPE{None,Char,WChar};
STYPE mtp=None;// тип строки
ADDRESS pnt;// указатель на строку
INT_W tl,rv;// тотальный размер и резерв
/** Сравнение строк */
LOGIC Compare(ADDRESS adr,INT_W sz){
return sz==sz?z::Compare(pnt,adr,sz):false;
}
public:
/** Конструктор строки для CHAR */
STRING(const CHAR *chs){*this=chs;}
/** Конструктор строки для WCHAR */
STRING(const WCHAR *chs){*this=chs;}
/** Конструктор строки с параметрами
* @param tl тотальный размер в памяти
* @param rv размер резервирования */
STRING(INT_W tl=0,INT_W rv=0):tl(tl),rv(rv){}
//STRING(const STRING &obj):POINTER<TCHAR>(obj.pnt){}
explicit operator bool(){
LOGIC res=false;
if(mtp){
if(mtp==Char){
if(((POINTER<CHAR>*)pnt)->Size())res=true;
}else{
if(((POINTER<WCHAR>*)pnt)->Size())res=true;
}
}
return res;
}
operator INT_W(){return mtp;}
/*template<typename dTYPE, typename = t::Enable<t::isBaseB<dTYPE>,dTYPE>>
STRING(dTYPE val){
POINTER<TCHAR> pch;
INT_W vid=::Type<dTYPE>::Id;
if(vid==1)pch=val?"true":"false";
else{sprintf(*pch,vid==11 || vid==12?"%f":"%d",val);pch.Size(true);}
*this=*pch;
}
TCHAR& operator[](INT_L idx){
z::Index(idx,sz);
return pnt[idx];
}*/
STRING& operator=(const CHAR *pch){
if(mtp!=Char){
if(mtp!=None)Clear();
pnt=new POINTER<CHAR>(pch);mtp=Char;
}else *(POINTER<CHAR>*)pnt=pch;
return *this;
}
STRING& operator=(const WCHAR *pch){
if(mtp!=WChar){
if(mtp!=None)Clear();
pnt=new POINTER<WCHAR>(pch);mtp=WChar;
}else *(POINTER<WCHAR>*)pnt=pch;
return *this;
}
void Clear(){
if(mtp){
if(mtp==Char)delete (POINTER<CHAR>*)pnt;
else delete (POINTER<WCHAR>*)pnt;
mtp=None;pnt=NULL;
}
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<< (std::ostream &out,STRING &obj){
TRY
if(obj.mtp==Char){
POINTER<CHAR> *chs=(POINTER<CHAR>*)obj.pnt;
out<<(chs->Size()?*chs:"NULL");
}
#ifdef FILE_error
else throw Error(_L("cout<<Значение строки не CHAR!"));
#endif
CATCH
return out;
}
friend std::wostream& operator<< (std::wostream &out,STRING &obj){
TRY
if(obj.mtp==WChar){
POINTER<WCHAR> *chs=(POINTER<WCHAR>*)obj.pnt;
out<<(chs->Size()?*chs:L"NULL");
}
#ifdef FILE_error
else throw Error(_L("wcout<<Значение строки не WCHAR!"));
#endif
CATCH
return out;
}
#endif
/*STRING& operator=(const STRING &obj){
sz=obj.sz;
if(TCHAR* npt=Change()){
delete []pnt;pnt=npt;
}else if(sz>tl)sz=tl;
Assign(obj.pnt);
return *this;
}
STRING& operator+=(const STRING &obj){
Put(obj);return *this;
}
STRING& operator-=(const STRING &obj){
this->Cut(obj);return *this;
}
LOGIC operator==(const STRING &obj){
return Compare(obj.pnt,obj.sz);
}
LOGIC operator!=(const STRING &obj){
return !Compare(obj.pnt,obj.sz);
}
/ ** Вставка подстроки
* @param obj подстрока
* @param idx индекс куда вставить * /
void Put(const STRING &obj,INT_W idx=0){
if(INT_W psz=obj.sz){
if(INT_L(sz+psz)>(rv?65535:tl))psz=(rv?65535:tl)-sz;
if(psz){
ADDRESS adr1,adr2,adr3;
INT_W osz=sz;sz+=psz;
if(!idx)idx=osz;else z::Index(idx,sz);
if(TCHAR* lts=Change()){
adr1=(ADDRESS)lts;adr2=(ADDRESS)pnt;
if(idx)z::Copy(adr1,adr2,idx);
adr3=(ADDRESS)obj.pnt;
z::Copy(adr1,adr3,psz);
z::Copy(adr1,adr2,osz-idx);
*(TCHAR*)adr1=0;
delete []pnt;pnt=lts;
}else{
adr1=adr2=(ADDRESS)pnt;
z::Shift(adr1,sz);z::Shift(adr2,osz);
*(TCHAR*)adr1=0;z::Copy(adr1,adr2,-(osz-idx));
adr3=(ADDRESS)obj.pnt;z::Shift(adr3,psz);
z::Copy(adr1,adr3,-psz);
}
}
}
}
/ ** Вырезать
* @param idx индекс места вырезки
* @param csz размер для вырезки * /
void Cut(INT_W idx=-1,INT_W csz=0){
if(sz){
if(!csz)csz++;
z::Index(idx,sz);
if(idx+csz>sz)csz=sz-idx;
if(csz){
ADDRESS adr1,adr2;
INT_W osz=sz;sz=sz-csz;
if(TCHAR* npt=Change()){
delete []pnt;pnt=npt;
adr1=(ADDRESS)npt;adr2=(ADDRESS)pnt;
if(idx)z::Copy(adr1,adr2,idx);
z::Shift(adr2,csz);idx+=csz;
z::Copy(adr1,adr2,osz-idx);
}else{
adr1=(ADDRESS)pnt;
if(idx)z::Shift(adr1,idx);
adr2=adr1;z::Shift(adr2,csz);
idx+=csz;z::Copy(adr1,adr2,osz-idx);
}
*(TCHAR*)adr1=0;
}
}
}
/ ** Вырезать
* @param obj подстрока
* @param idx индекс поиска * /
void Cut(const STRING &obj,INT_W idx=0){
idx=this->Find(obj,idx);
if(idx)Cut(idx,obj.sz);
}
/ ** Поиск позиции подстроки
* @param obj подстрока
* @param idx индекс начала поиска
* @return индекс позиции * /
INT_W Find(const STRING &obj,INT_W idx=0){
INT_W res=0;
if(sz){
LOGIC sgn=idx>sz?false:true;
ADDRESS adr=pnt;
z::Index(idx,sz);if(idx>0)z::Shift(adr,idx);
if(sgn){
for(INT_W nx=sz-obj.sz;idx<=nx;idx++){
if(z::Compare(adr,obj.pnt,obj.sz)){res=idx+1;break;}
z::Shift(adr);
}
}else if(idx-obj.sz>0){
for(INT_W nx=idx-obj.sz;idx>0;idx--){
if(z::Compare(adr,obj.pnt,obj.sz)){res=idx+1;break;}
z::Shift(adr,-1);
}
}
}
return res;
}
void Kill()=delete;
*/
};
ID_TYPE(15,STRING)
ID_TYPE(35,POINTER<STRING>)
/* * ДатаВремя * /
class DATETIME {
time_t dtm;
public:
DATETIME(time_t dtm=0){this->dtm=dtm;}
DATETIME(const DATETIME &obj):dtm(obj.dtm){}
operator INT_B(){return (INT_B)dtm;}
operator DateTime(){
DateTimeU udt;
udt.stm=*localtime(&dtm);
udt.dtm.year+=1900;
udt.dtm.month+=1;
return udt.dtm;
}
DATETIME& operator=(time_t val){
this->dtm=val;return *this;
}
DATETIME& operator=(DateTime dtm){
DateTimeU udt;
udt.dtm=dtm;
udt.dtm.month-=1;
udt.dtm.year-=1900;
this->dtm=mktime(&udt.stm);
return *this;
}
DATETIME& operator+=(time_t val){
this->dtm+=val;return *this;
}
DATETIME& operator-=(time_t val){
this->dtm-=val;return *this;
}
/ ** Время выполнения * /
void Clock(){this->dtm=clock();}
/ ** Текущее время * /
void Now(){this->dtm=time(NULL);}
/ ** Получение строкового представления даты-времени
* @param fmt формат даты-времени
* @param bsz размер буфера формирования строки
* @return строка с датой-временем * /
STRING Format(STRING fmt=_L("%Y.%m.%d %H:%M:%S"),INT_W sbf=64){
TCHAR res[sbf];
#ifndef UNICODE
strftime(res,sbf,*fmt,localtime(&dtm));
#else
wcsftime(res,sbf,*fmt,localtime(&dtm));
#endif
return STRING(res);
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<< (std::ostream &out,const DATETIME &obj){
return out<<obj.dtm;
}
friend std::wostream& operator<< (std::wostream &out,const DATETIME &obj){
return out<<obj.dtm;
}
#endif
};
ID_TYPE(16,DATETIME)
//ID_TYPE(17,резерв)
//ID_TYPE(18,резерв)
/ ** Пространство имёт от _types * /
namespace t {
/ ** Проверка на основной тип данных * /
template <typename dTYPE>
constexpr bool isBaseA=IsMatch<dTYPE,LOGIC,CHAR,RANGE,BYTE,INT_S,INT_W,WCHAR,INT_M,INT_L,INT_T,INT_B,FLOAT,DOUBLE,ADDRESS,STRING,DATETIME>::v;
/ ** Получение Id переменной
* @param var переменная
* @return Id переменной * /
template<typename dTYPE>
INT_W Id(dTYPE var){
return ::Type<dTYPE>::Id;
}
/ ** Получение типа переменной
* @param var переменная
* @return тип переменной * /
template<typename dTYPE>
STRING Type(dTYPE var){
STRING vtp;
if(::Type<dTYPE>::Id)vtp=::Type<dTYPE>::Name;
else{vtp=typeid(var).name();
INT_W nx=0,sz=vtp.Size();
while(nx++<sz){BYTE sb=vtp[nx];
if(sb<48 || sb>57){nx--;break;}
}
vtp.Cut(1,nx);
}
return vtp;
}
}
/ * * Ссылка * /
class LINK {
protected:
STRING tp;
ADDRESS pnt=NULL;
INT_W id=0,sz=0;
public:
LINK(){}
template<typename dTYPE>
LINK(dTYPE &obj){this->Init(obj);}
LINK(const LINK &obj):tp(obj.tp),id(obj.id),sz(obj.sz),pnt(obj.pnt){}
ADDRESS operator*(){return pnt;}
//operator CHAR*(){return (CHAR*)pnt;}
template <typename dTYPE>
operator dTYPE(){return *(dTYPE*)pnt;}
explicit operator bool(){return pnt?true:false;}
template<typename dTYPE>
t::Enable<t::isBaseA<dTYPE>,LINK&> operator=(dTYPE val){
TRY
if(id==::Type<dTYPE>::Id)*(dTYPE*)pnt=val;
#ifdef FILE_error
else throw Error("LINK = не соответствует типу!");
#endif
CATCH
return *this;
}
template<typename dTYPE>
t::Enable<t::isBaseA<dTYPE>,LOGIC> operator==(dTYPE val){
LOGIC res=false;
TRY
if(id==::Type<dTYPE>::Id)res=*(dTYPE*)pnt==val;
#ifdef FILE_error
else throw Error("LINK == не соответствует типу!");
#endif
CATCH
return res;
}
template<typename dTYPE>
t::Enable<t::isBaseA<dTYPE>,LOGIC> operator!=(dTYPE val){
LOGIC res=false;
TRY
if(id==::Type<dTYPE>::Id)res=*(dTYPE*)pnt!=val;
#ifdef FILE_error
else throw Error("LINK == не соответствует типу!");
#endif
CATCH
return res;
}
/ ** Получение Id данных * /
INT_W Id(){return id;}
/ ** Размер данных * /
INT_W Size(){return sz;}
/ ** Тип данных * /
STRING Type(){return tp;}
/ ** Инициализация
* @param obj объект * /
template<typename dTYPE>
void Init(dTYPE &obj){
pnt=&obj;tp=t::Type(obj);id=::Type<dTYPE>::Id;sz=sizeof(dTYPE);
}
/ ** Инициализация
* @param chs массив символов * /
void Init(const TCHAR *chs){
pnt=(ADDRESS)chs;
sz=z::Lsize(chs);
id=::Type<TCHAR>::Id;
tp=::Type<TCHAR>::Name;
}
/ ** Очистка ссылки * /
void Clear(){
sz=id=0;tp=_L("");pnt=NULL;
}
#ifdef _GLIBCXX_IOSTREAM
friend std::ostream& operator<<(std::ostream &out,const LINK &obj){
if(obj.pnt){
switch(obj.id){
case 1: out<<(*(LOGIC*)obj.pnt?"true":"false");break;
case 2: out<<*(CHAR*)obj.pnt;break;
case 3: out<<(INT_S)*(RANGE*)obj.pnt;break;
case 4: out<<(INT_W)*(BYTE*)obj.pnt;break;
case 5: out<<*(INT_S*)obj.pnt;break;
case 6: out<<*(INT_W*)obj.pnt;break;
case 7: out<<*(WCHAR*)obj.pnt;break;
case 8: out<<*(INT_M*)obj.pnt;break;
case 9: out<<*(INT_L*)obj.pnt;break;
case 10:out<<*(INT_T*)obj.pnt;break;
case 11:out<<*(INT_B*)obj.pnt;break;
case 12:out<<*(FLOAT*)obj.pnt;break;
case 13:out<<*(DOUBLE*)obj.pnt;break;
case 14:out<<*(ADDRESS*)obj.pnt;break;
case 15:out<<*(STRING*)obj.pnt;break;
case 16:out<<*(DATETIME*)obj.pnt;break;
case 32:out<<*(POINTER<CHAR>*)obj.pnt;break;
case 37:out<<*(POINTER<WCHAR>*)obj.pnt;break;
default:out<<obj.tp;
}
}else out<<"NULL";
return out;
}
#endif
};
ID_TYPE(19,LINK)
*/
/** Обработка ошибок
* Библиотека OWNI */
#pragma once
#define FILE_winapi
#include <windows.h>
#include "_types.hpp"
namespace w {
/** Конвертация UTF8 в ANSI
* @param chs указатель на массив символов
* @return массив символов в ANSI */
POINTER<CHAR> utf8_ansi(const CHAR *chs){
INT_W sz=z::Lsize(chs);
POINTER<CHAR> res(sz);
POINTER<WCHAR> wch(sz);
MultiByteToWideChar(CP_UTF8,0,chs,-1,*wch,sz);
WideCharToMultiByte(CP_ACP,0,*wch,-1,*res,sz,NULL,NULL);
res.Size(true);
return res;
}
}
/** Изюминки, вспомогательные функции
* Библиотека OWNI */
#pragma once
#define FILE_zests
#ifndef FILE_types
#include "_types.hpp"
#endif
/** Пространство имёт от _zests */
namespace z {
/** Поменять местами переменные
* @param vr1 переменная 1
* @param vr2 переменная 2 */
template <typename dTYPE>
void Swap(dTYPE &vr1, dTYPE &vr2){
dTYPE tmp(vr1);vr1=vr2;vr2=tmp;
}
/** Поменять местами указатели
* @param vr1 указатель переменной 1
* @param vr2 указатель переменной 2 */
template <typename dTYPE>
void Swap(dTYPE *vr1, dTYPE *vr2){
dTYPE tmp(*vr1);*vr1=*vr2;*vr2=tmp;
}
/** Сдвиг указателя
* @param pnt указатель
* @param shift смещение */
template <typename dTYPE>
void Shift(dTYPE* &pnt,INT_S shift=1){
pnt+=shift;
}
/** Сдвиг указателя
* @param adr указатель
* @param shift смещение */
void Shift(ADDRESS &adr,INT_S shift=1){
adr=(ADDRESS*)((INT_B)adr+shift);
}
/** Заполнение памяти значением
* @param pnt указатель адреса
* @param size размер\\длинна
* @param val значение */
template <typename dTYPE=BYTE>
void Fill(ADDRESS &adr,INT_W size,dTYPE val=0){
while(size>0){
*(dTYPE*)adr=val;Shift(adr,sizeof(dTYPE));size--;
}
}
/** Перенос данных их одной области в другую
* @param adr1 адрес куда переносим
* @param adr2 адрес откуда переносим
* @param cnt счётчик\\количество итераций */
template <typename dTYPE=BYTE>
inline void Same(ADDRESS &adr1,ADDRESS &adr2,INT_M cnt){
if(cnt){INT_S shi=sizeof(dTYPE);
if(cnt<0){shi=-shi;cnt=-cnt;}
do{
*(dTYPE*)adr1=*(dTYPE*)adr2;
Shift(adr1,shi);Shift(adr2,shi);
}while(--cnt>0);
}
}
/** Копирование в памяти
* @param adr1 адрес куда копировать
* @param adr2 адрес от куда копировать
* @param size размер\\длинна */
void Copy(ADDRESS &adr1,ADDRESS &adr2,INT_M size){
INT_M cnt;
BYTE dis=(size>0?(INT_B)adr2-(INT_B)adr1:(INT_B)adr1-(INT_B)adr2)%255;
cnt=size/8;if(cnt && dis>=8){size=size%8;Same<INT_B>(adr1,adr2,cnt);}
cnt=size/4;if(cnt && dis>=4){size=size%4;Same<INT_L>(adr1,adr2,cnt);}
cnt=size/2;if(cnt && dis>=2){size=size%2;Same<INT_W>(adr1,adr2,cnt);}
if(size>0){cnt=size;Same(adr1,adr2,cnt);}
}
/** Сравнение памяти
* @param adr1 указатель адреса 1
* @param adr2 указатель адреса 2
* @param size размер\\длинна
* @return `true` равно, `false` не равно */
LOGIC Compare(ADDRESS adr1,ADDRESS adr2,INT_W size){
LOGIC res=true;
while(size>0 && res){
if(size>=8){
if(*(INT_B*)adr1!=*(INT_B*)adr2)res=false;
else{Shift(adr1,8);Shift(adr2,8);size-=8;}
}else if(size>=4){
if(*(INT_L*)adr1!=*(INT_L*)adr2)res=false;
else{Shift(adr1,4);Shift(adr2,4);size-=4;}
}else if(size>=2){
if(*(INT_W*)adr1!=*(INT_W*)adr2)res=false;
else{Shift(adr1,2);Shift(adr2,2);size-=2;}
}else{
if(*(BYTE*)adr1!=*(BYTE*)adr2)res=false;
else{Shift(adr1,1);Shift(adr2,1);size-=1;}
}
}
return res;
}
/** Валидация индекса
* @param idx индекс
* @param asz размер массива */
void Index(INT_W &idx,INT_W asz){
if(idx>0){
if(asz>0){
if(idx<=asz)idx--;
else{idx=~idx+1;
if(idx<=asz)idx=asz-idx;
else idx=asz-1;
}
}else idx=0;
}
}
/** Валидация индекса
* @param idx индекс
* @param asz размер массива */
void Index(INT_L &idx,INT_L asz){
if(idx>0){
if(asz>0){
if(idx<=asz)idx--;
else{idx=~idx+1;
if(idx<=asz)idx=asz-idx;
else idx=asz-1;
}
}else idx=0;
}
}
/** Расчёт объёма от размера и резерва
* @param sz текущий размер
* @param rv резерв памяти
* @return значение объёма */
INT_W Volume(INT_W sz,INT_W rv){
INT_L res=rv+(sz/rv)*rv;
if(res>65535)res=65535;
return res;
}
/** Расчёт объёма от размера и резерва
* @param sz текущий размер
* @param rv резерв памяти
* @return значение объёма */
INT_L Volume(INT_L sz,INT_W rv){
INT_B res=rv+(sz/rv)*rv;
if(res>4294967295)res=4294967295;
return res;
}
/** Получение длинны массива символов
* @param chs массив символов
* @return размер массива символов */
INT_W Lsize(const CHAR *chs){
INT_W sz=0;
while (*chs++){sz++;if(sz==65535)break;}
return sz;
}
INT_W Lsize(const WCHAR *chs){
INT_W sz=0;
while (*chs++){sz++;if(sz==65535)break;}
return sz;
}
}