#include "xy.h"
#include <intrin.h>
/* Plotdaten können in allgemeiner Form übergeben werden:
- Datentyp int8_t, int16_t, int32_t, int64_t, float, double,
bool, uint8_t, uint16_t, Funktionszeiger
getrennt für X und Y
- XY-Daten getrennt oder verschachtelt
*/
static int fINF=0x000000FF;
static int fNAN=0xFFFFFFFF;
#define INF (*(float*)fINF);
#define NAN (*(float*)fNAN);
template<typename T> class Datareader{
virtual T get() const =0;
virtual T operator()() =0;
};
template<typename T> class DatareaderN:public Datareader<T>{ // <T> ist "float" oder "double"
static T takeint(int val,int infbase) {
int infnan=val-infbase;
if ((unsigned)infnan>=3) return val;
switch (infnan) {
case 0: return +INF;
case 2: return -INF;
default: return NAN;
}
}
public:
T takeu8() const {return *data.cb;}
T takeu16() const {return *data.ch;}
T takeu32() const {return *data.cw;}
T takei8() const {return takeint(*data.cc,0x7F);}
T takei16() const {return takeint(*data.cs,0x7FFF);}
T takei32() const {return takeint(*data.cl,0x7FFFFFFF);}
T takefloat() const {return *data.cf;}
T takedouble() const {return *data.cd;}
typedef T (Datareader::*getfcn)() const;
enum typ{
U8,U16,U32,I8,I16,I32,F32,F64
};
private:
static getfcn getters[]; // Liste der 8 Entnahmefunktionen
DATA data; // Laufender Datenzeiger
getfcn getter; // Aktuelle Entnahmefunktion (statt einem Rudel abgeleiteter Klassen)
int increment; // Sprungweite des Datenzeigers in Bytes
public:
T get() const {return (this->*getter)();}
// Parameterliste: Datenzeiger, Werttyp, Sprungweite des Zeigers zum nächsten Wert in Bytes
DatareaderN(const void*_data,typ _typ,int _increment) {
data.cv=_data;
getter=getters[_typ]; // Funktionszeiger setzen
increment=_increment;
}
T operator()() {
T r=get();
data.cb+=increment;
return r;
}
};
DatareaderN<double>::getfcn DatareaderN<double>::getters[]={
(DatareaderN<double>::getfcn)&DatareaderN::takeu8,
(DatareaderN<double>::getfcn)&DatareaderN::takeu16,
(DatareaderN<double>::getfcn)&DatareaderN::takeu32,
(DatareaderN<double>::getfcn)&DatareaderN::takei8,
(DatareaderN<double>::getfcn)&DatareaderN::takei16,
(DatareaderN<double>::getfcn)&DatareaderN::takei32,
(DatareaderN<double>::getfcn)&DatareaderN::takefloat,
(DatareaderN<double>::getfcn)&DatareaderN::takedouble};
template<typename T> class DatareaderFcn:public Datareader<T>{
public:
typedef T (*fcn_t)(T);
DatareaderFcn(fcn_t _fcn,T _start, T _increment){
fcn=_fcn;
start=_start;
increment=_increment;
}
T get() const {return fcn(start);}
T operator()() {
T r=get(); start+=increment; return r;
}
private:
fcn_t fcn;
T start, increment;
};
template<typename T> class DatareaderBits:public Datareader<T>{
public:
DatareaderBits(const void*_mem, int _numbits=1, int increment=0, int index=0){
mem.cv=_mem;
numbits=_numbits;
if (!_increment) _increment=_numbits;
increment=_increment;
index=_index;
}
T get() const {return *(DWORD*)(mem.cb+index>>3)>>(index&7)&(1<<numbits)-1;}
T operator()() {
T r=fcn(start); index+=increment; return r;
}
private:
DATA mem;
int index,numbits,increment;
};
#include <stdio.h>
void test() {
static const float data[]={1,2,3,4};
DatareaderN<double> dr(data,DatareaderN<double>::F32,sizeof(float));
double t=dr.get();
for (int i=0; i<elemof(data); i++) printf("%f",dr());
}
/*** Plot ***/
bool Plot::stroke::check() {
if (!okay) {
pen=new Gdiplus::Pen(42,3);
len=1024;
points=new Gdiplus::Point[len];
okay=true;
}
return okay;
}
void Plot::onPaint(Gdiplus::Graphics&g) {
if (s.check()) {
g.DrawLines(s.pen,s.points,s.len);
}
}
Vorgefundene Kodierung: UTF-8 | 0
|