Browse Source

Gmt module: Rewrite Conver2Struct and its derivatives in form appropriate for new parameters parsing scheme.

gmtdatadir
Michael Uleysky 8 years ago
parent
commit
8a088d14c3
  1. 373
      modules/gmt/modgmt_func.h

373
modules/gmt/modgmt_func.h

@ -2,6 +2,7 @@
#define MODGMT_FUNC_H
#include "modgmt_internals.h"
#include "modgmt_objects.h"
#include "modgmt_param.h"
const ObjectBase* GMT_Header(const ObjectList* input);
const ObjectBase* GMT_Footer(const ObjectList* input);
@ -11,36 +12,16 @@ const ObjectBase* GMT_ColorHSV(const ObjectList* input);
const ObjectBase* GMT_ColorCMYK(const ObjectList* input);
const ObjectBase* GMT_LayerShift(const ObjectList* input);
// Extension of OBTypeM template for easy work with lists
template<template<typename> class Func, class... O>
class Base2Something: public OBTypeM<Func,O...>
{
Base2Something() = delete;
Base2Something(Base2Something&&) = delete;
Base2Something(Base2Something&) = delete;
public:
Base2Something(const ObjectBase* arg):OBTypeM<Func,O...>(arg) {};
Base2Something(const ObjectList* input, const std::string& name):OBTypeM<Func,O...>(input->Find(name)){};
Base2Something(const ObjectList* input, const ObjectList::IndexType i):OBTypeM<Func,O...>((i<input->Size())?input->At(i):0){}; // Check index, because At is not safe
template<class... Args>
auto operator ()(bool* b, Args... args) const -> decltype(this->OBTypeM<Func,O...>::template operator()<bool*, Args...>(b, args...))
{
if(!OBTypeM<Func,O...>::operator bool()) *b=false;
return OBTypeM<Func,O...>::operator ()(b,args...);
}
};
// Generic converting template
template<class Struct, class O>
class Convert2Struct
{
public:
template<class... Args>
Struct operator()(const O* o, bool* suc, Args... args) const
Struct operator()(const O* o, bool* suc, std::string& err, Args... args) const
{
Struct s;
if(!s.Convert(o->Value(),args...)) *suc=false;
if(!s.Convert(o->Value(),err,args...)) *suc=false;
return s;
}
};
@ -50,7 +31,7 @@ class Convert2Struct<Struct, ObjectGMTClass<Struct> >
{
public:
template<class... Args>
Struct operator()(const ObjectGMTClass<Struct>* o, bool* suc, Args... args) const { return o->Data(); }
Struct operator()(const ObjectGMTClass<Struct>* o, bool* suc, std::string& err, Args... args) const { return o->Data(); } // Never return error
};
// Converting Int or Real to double
@ -58,14 +39,21 @@ template<class O>
class Convert2Struct<double,O>
{
public:
double operator ()(const O* q, bool* suc) const {return q->Value();}
double operator ()(const O* q, bool* suc, std::string& err) const {return q->Value();}
};
// Converting String to double
template<>
class Convert2Struct<double,ObjectString>
{
public:
double operator ()(const ObjectString* q, bool* suc) const {double d=0; *suc=(*suc) && str2double(q->Value(),&d); return d;}
double operator ()(const ObjectString* q, bool* suc, std::string& err) const
{
double d=0;
bool res=str2double(q->Value(),&d);
if(!res) err="Can't convert string "+q->Value()+" to double";
*suc=(*suc) && res;
return d;
}
};
// Converting Int or Real to bool
@ -73,19 +61,20 @@ template<class O>
class Convert2Struct<bool,O>
{
public:
bool operator ()(const O* q, bool* suc) const {return q->Value()!=0;}
bool operator ()(const O* q, bool* suc, std::string& err) const {return q->Value()!=0;}
};
// Converting String to bool
template<>
class Convert2Struct<bool,ObjectString>
{
public:
bool operator ()(const ObjectString* q, bool* suc) const
bool operator ()(const ObjectString* q, bool* suc, std::string& err) const
{
std::string v=q->Value();
tolower(v);
if("y"==v || "yes"==v || "on"==v || "t"==v || "true"==v || "1"==v) return true;
if("n"==v || "no"==v || "off"==v || "f"==v || "false"==v || "0"==v) return false;
err="Can't convert string "+q->Value()+" to bool";
*suc=false;
return false;
}
@ -96,280 +85,130 @@ template<>
class Convert2Struct<std::string,ObjectString>
{
public:
std::string operator ()(const ObjectString* q, bool* suc) const {return q->Value();}
std::string operator ()(const ObjectString* q, bool* suc, std::string& err) const {return q->Value();}
};
// This class search parameter with specified names in the list, which may be converted to Struct.
// If SearchByType is true, additionaly search unnamed parameter of corresponding Object class (ObjectGMTClass<Struct> for gmt_struct-derived types, for example).
// Additionally, Policies can be used to check correctness of found parameter.
template<class Struct, bool SearchByType=true, class... Policies>
class SearchParameter;
template<class Struct, bool SearchByType=true, class... Policies>
class SearchParameterWDef;
// Generic type storage class
template<class Struct,class... Types>
class gTypeStorage
{
template<class O> class Convertor: public Convert2Struct<Struct, O> {}; // Conversion type
public:
typedef Base2Something<Convertor,Types...> Base2Type;
typedef SearchParameter<Struct,false> BaseM2Type;
typedef SearchParameter<Struct,true> BaseMT2Type;
typedef SearchParameterWDef<Struct,false> BaseMD2Type;
typedef SearchParameterWDef<Struct,true> BaseMTD2Type;
};
// Specific type storage class
template<class Struct>
class TypeStorage;
// Default ObjectList converter
template<class Struct>
class Convert2Struct<Struct, ObjectList>
// Generic template for Converter class (using for read parameters)
template<class Struct, class... Types>
class BaseConverter
{
template<class O> class StructConvertor: public Convert2Struct<Struct, O> {}; // Conversion type
public:
using ValueType=Struct;
template<class... Args>
Struct operator()(const ObjectList* o, bool* suc, Args... args) const
ValueType Convert(const ObjectBase* ob, bool* res, std::string& err, Args... args)
{
Struct s;
if(o->Size()!=1) {*suc=false; return s;}
typename TypeStorage<Struct>::Base2Type a(o,0);
s=a(suc,args...);
return s;
}
};
// Helper struct for class SearchParameter
template<class Struct, bool check>
// Search function for non-gmt_struct types do nothing
struct SearchHelper {void operator()(const ObjectList* input, Struct* s, bool* exist, bool* ok) const {}};
template<class Struct>
// Search function for gmt_struct types find ObjectGMTClass<Struct> in list
struct SearchHelper<Struct,true>
{
void operator()(const ObjectList* input, Struct* s, bool* exist, bool* ok) const
{
for(ObjectList::IndexType i=0;i<input->Size();i++)
OBTypeM<StructConvertor,Types...> gp(ob);
switch(gp.Error())
{
OBType<ObjectGMTClass<Struct> > obj(input->At(i));
if(obj)
{
if(*exist) {*ok=false; break;} // Object already found
*s=obj->Data();
*exist=true;
}
case(OBTypeErr::OK): return gp(res,std::ref(err),args...);
case(OBTypeErr::NULLPTR): {err="Can't convert zero ObjectBase pointer to something meaningfull"; break;}
case(OBTypeErr::TYPEMISMATCH): {err="Can't convert "+ob->Type()+": type mismatch"; break;}
}
*res=false;
return ValueType();
}
};
// Definition without policies
template<class Struct, bool SearchByType>
class SearchParameter<Struct,SearchByType>
// Generic template for Converter class with default value (using for read parameters)
template<class B>
class DefaultConverter: public B
{
typedef typename TypeStorage<Struct>::Base2Type Base2Struct;
protected:
bool exist; // There is at least one parameter with given names
bool ok; // True if conversion to corresponding structure was successful and there is only one parameter with given names
Struct val;
SearchParameter() = delete;
SearchParameter(SearchParameter&&) = delete;
SearchParameter(SearchParameter&) = delete;
public:
// Recursive constructor
using ValueType=typename B::ValueType;
private:
ValueType def;
public:
DefaultConverter() = delete;
template<class... Args>
SearchParameter(const ObjectList* input, const std::string& name, Args... args):SearchParameter(input,args...)
{
if(ok)
{
Base2Struct a(input,name);
if(exist && a.Exist()) ok=false;
else if(a.Exist())
{
exist=true;
ok=true;
val=a(&ok);
}
}
}
// Bottom of recursion
SearchParameter(const ObjectList* input):exist(false),ok(true) {SearchHelper<Struct,SearchByType>()(input,&val,&exist,&ok);}
// Search by index
SearchParameter(const ObjectList* input, const ObjectList::IndexType i):exist(false),ok(true)
{
Base2Struct a(input,i);
if(a.Exist())
{
exist=true;
val=a(&ok);
}
}
Struct operator()(bool* suc) const
{
if(!ok || !exist) *suc=false;
return val;
}
Struct operator()(bool* ex, bool* suc) const
{
*ex=exist;
if(!ok || !exist) *suc=false;
return val;
}
bool Exist() const {return exist;}
DefaultConverter(const ValueType& d, Args... args):B(args...),def(d) {}
template<class... Args>
DefaultConverter(ValueType&& d, Args... args):B(args...),def(std::move(d)) {}
const ValueType& Default() const {return def;}
};
// Definition with policies
template<class Struct, bool SearchByType, class Policy, class... Policies>
class SearchParameter<Struct,SearchByType,Policy,Policies...>: public SearchParameter<Struct,SearchByType,Policies...>
// Here we store type of Converter to type Struct. Generic template must never be used.
template<class Struct> class TypeStorage;
template<> class TypeStorage<double> {public: typedef BaseConverter<double, ObjectReal, ObjectInt, ObjectString > Converter;};
template<> class TypeStorage<bool> {public: typedef BaseConverter<bool, ObjectInt, ObjectReal, ObjectString > Converter;};
template<> class TypeStorage<std::string> {public: typedef BaseConverter<std::string, ObjectString > Converter;};
template<> class TypeStorage<struct gmt_coord> {public: typedef BaseConverter<struct gmt_coord, ObjectReal, ObjectInt, ObjectString,ObjectGMTCoord,ObjectList> Converter;};
template<> class TypeStorage<struct gmt_region> {public: typedef BaseConverter<struct gmt_region, ObjectList, ObjectString,ObjectGMTRegion > Converter;};
template<> class TypeStorage<struct gmt_projection> {public: typedef BaseConverter<struct gmt_projection,ObjectList, ObjectGMTProjection > Converter;};
template<> class TypeStorage<struct gmt_color> {public: typedef BaseConverter<struct gmt_color, ObjectList, ObjectString,ObjectReal,ObjectInt, ObjectGMTColor > Converter;};
template<> class TypeStorage<struct gmt_dash> {public: typedef BaseConverter<struct gmt_dash, ObjectString,ObjectGMTDash > Converter;};
template<> class TypeStorage<struct gmt_pen> {public: typedef BaseConverter<struct gmt_pen, ObjectList, ObjectString,ObjectReal,ObjectInt, ObjectGMTPen > Converter;};
template<> class TypeStorage<struct gmt_font> {public: typedef BaseConverter<struct gmt_font, ObjectList, ObjectString,ObjectReal,ObjectInt, ObjectGMTFont > Converter;};
template<> class TypeStorage<struct gmt_layer> {public: typedef BaseConverter<struct gmt_layer, ObjectList, ObjectGMTLayer > Converter;};
// Default ObjectList converter
template<class Struct>
class Convert2Struct<Struct, ObjectList>
{
SearchParameter() = delete;
SearchParameter(SearchParameter&&) = delete;
SearchParameter(SearchParameter&) = delete;
public:
using SearchParameter<Struct,SearchByType,Policies...>::ok;
using SearchParameter<Struct,SearchByType,Policies...>::exist;
// Recursive constructor
template<class... Args>
SearchParameter(const ObjectList* input, Args... args):SearchParameter<Struct,SearchByType,Policies...>(input,args...) {}
Struct operator()(bool* suc) const
{
return Policy()(SearchParameter<Struct,SearchByType,Policies...>::operator()(suc),suc);
}
Struct operator()(bool* ex, bool* suc) const
Struct operator()(const ObjectList* o, bool* suc, std::string& err, Args... args) const
{
return Policy()(SearchParameter<Struct,SearchByType,Policies...>::operator()(suc),suc);
Struct s;
if(o->Size()!=1) {*suc=false; err="Can't convert list with more (or less) than one elements"; return s;}
typename TypeStorage<Struct>::Converter a;
s=a.Convert(o->At(0),suc,err,args...);
return s;
}
};
// SearchParameter with default value
template<class Struct, bool SearchByType, class... Policies>
class SearchParameterWDef: protected SearchParameter<Struct,SearchByType,Policies...>
// Template for simple aliases of convertors
template<class Struct>
using Base2Struct=typename TypeStorage<Struct>::Converter;
// Template for simple aliases of convertors with default values
template<class Struct>
using Base2StructD=DefaultConverter<typename TypeStorage<Struct>::Converter>;
// Simple aliases of convertors
using Base2Double=Base2Struct<double>;
using Base2String=Base2Struct<std::string>;
using Base2Coord =Base2Struct<struct gmt_coord>;
using Base2Region=Base2Struct<struct gmt_region>;
using Base2Proj =Base2Struct<struct gmt_projection>;
// Simple aliases of convertors with default values
using Base2StringD=Base2StructD<std::string>;
// Specialised convertors
// Convertor with default value for gmt_coord. Added constructor for creating default value from double argument
class Base2CoordD: public DefaultConverter<Base2Coord>
{
typedef SearchParameter<Struct,SearchByType,Policies...> SP;
SearchParameterWDef() = delete;
SearchParameterWDef(SearchParameterWDef&&) = delete;
SearchParameterWDef(SearchParameterWDef&) = delete;
public:
template<class... Args>
SearchParameterWDef(const ObjectList* input, const Struct& def, Args... args):SP(input,args...)
static ValueType Def(double d)
{
if(!SP::exist) SP::val=def;
SP::exist=true;
ValueType v;
std::string fake;
v.Convert(d,fake);
return v;
}
Struct operator()(bool* suc) const {return SP::operator()(suc);}
Struct operator()(bool* ex, bool* suc) const {return SP::operator()(ex,suc);}
bool Exist() const {return true;}
public:
using ValueType=DefaultConverter<Base2Coord>::ValueType;
Base2CoordD(double d):DefaultConverter<Base2Coord>(Def(d)) {}
};
// SearchParameter with default value setted as class
template<class Struct, class DefClass, bool SearchByType=false, class... Policies>
class SearchParameterWDefO: protected SearchParameter<Struct,SearchByType,Policies...>
// Convertors for double non-negative value
class Base2NonNeg: public Base2Double
{
typedef SearchParameter<Struct,SearchByType,Policies...> SP;
SearchParameterWDefO() = delete;
SearchParameterWDefO(SearchParameterWDefO&&) = delete;
SearchParameterWDefO(SearchParameterWDefO&) = delete;
public:
template<class... Args>
SearchParameterWDefO(const ObjectList* input, Args... args):SP(input,args...)
double Convert(const ObjectBase* ob, bool* res, std::string& err)
{
if(!SP::exist) SP::val=DefClass()();
SP::exist=true;
double t=Base2Double::Convert(ob,res,err);
if(res && t<=0)
{
*res=false;
err="Value mast be greater then zero";
}
return t;
}
Struct operator()(bool* suc) const {return SP::operator()(suc);}
Struct operator()(bool* ex, bool* suc) const {return SP::operator()(ex,suc);}
bool Exist() const {return true;}
};
// Class for default double value
// We use rational representation of floating point number, because double type values not allowed as template parameter
template<int32_t num=0, uint32_t denum=1>
class DoubleDefaultVal
{
DoubleDefaultVal(DoubleDefaultVal&&) = delete;
DoubleDefaultVal(DoubleDefaultVal&) = delete;
public:
DoubleDefaultVal(){};
double operator()() const {return static_cast<double>(num)/denum;}
};
// Definitions for double
template<> class TypeStorage<double>: public gTypeStorage<double,ObjectReal,ObjectInt,ObjectString> {};
typedef TypeStorage<double>::Base2Type Base2Double;
typedef TypeStorage<double>::BaseM2Type BaseM2Double;
typedef TypeStorage<double>::BaseMT2Type BaseMT2Double;
typedef TypeStorage<double>::BaseMD2Type BaseMD2Double;
typedef TypeStorage<double>::BaseMTD2Type BaseMTD2Double;
// Definitions for bool
template<> class TypeStorage<bool>: public gTypeStorage<bool,ObjectInt,ObjectReal,ObjectString> {};
typedef TypeStorage<bool>::Base2Type Base2Bool;
typedef TypeStorage<bool>::BaseM2Type BaseM2Bool;
typedef TypeStorage<bool>::BaseMT2Type BaseMT2Bool;
typedef TypeStorage<bool>::BaseMD2Type BaseMD2Bool;
typedef TypeStorage<bool>::BaseMTD2Type BaseMTD2Bool;
// Definitions for string
template<> class TypeStorage<std::string>: public gTypeStorage<std::string,ObjectString> {};
typedef TypeStorage<std::string>::Base2Type Base2String;
typedef TypeStorage<std::string>::BaseM2Type BaseM2String;
typedef TypeStorage<std::string>::BaseMT2Type BaseMT2String;
typedef TypeStorage<std::string>::BaseMD2Type BaseMD2String;
typedef TypeStorage<std::string>::BaseMTD2Type BaseMTD2String;
// Definitions for ObjectGMTCoord
template<> class TypeStorage<struct gmt_coord>: public gTypeStorage<struct gmt_coord,ObjectReal,ObjectInt,ObjectString,ObjectGMTCoord,ObjectList> {};
typedef TypeStorage<struct gmt_coord>::Base2Type Base2Coord;
typedef TypeStorage<struct gmt_coord>::BaseM2Type BaseM2Coord;
typedef TypeStorage<struct gmt_coord>::BaseMT2Type BaseMT2Coord;
typedef TypeStorage<struct gmt_coord>::BaseMD2Type BaseMD2Coord;
typedef TypeStorage<struct gmt_coord>::BaseMTD2Type BaseMTD2Coord;
// Definitions for ObjectGMTRegion
template<> class TypeStorage<struct gmt_region>: public gTypeStorage<struct gmt_region,ObjectList,ObjectString,ObjectGMTRegion> {};
typedef TypeStorage<struct gmt_region>::Base2Type Base2Region;
typedef TypeStorage<struct gmt_region>::BaseM2Type BaseM2Region;
typedef TypeStorage<struct gmt_region>::BaseMT2Type BaseMT2Region;
typedef TypeStorage<struct gmt_region>::BaseMD2Type BaseMD2Region;
typedef TypeStorage<struct gmt_region>::BaseMTD2Type BaseMTD2Region;
// Definitions for ObjectGMTProjection
template<> class TypeStorage<struct gmt_projection>: public gTypeStorage<struct gmt_projection,ObjectList,ObjectGMTProjection> {};
typedef TypeStorage<struct gmt_projection>::Base2Type Base2Projection;
typedef TypeStorage<struct gmt_projection>::BaseM2Type BaseM2Projection;
typedef TypeStorage<struct gmt_projection>::BaseMT2Type BaseMT2Projection;
typedef TypeStorage<struct gmt_projection>::BaseMD2Type BaseMD2Projection;
typedef TypeStorage<struct gmt_projection>::BaseMTD2Type BaseMTD2Projection;
// Definitions for ObjectGMTColor
template<> class TypeStorage<struct gmt_color>: public gTypeStorage<struct gmt_color,ObjectList,ObjectString,ObjectReal,ObjectInt,ObjectGMTColor> {};
typedef TypeStorage<struct gmt_color>::Base2Type Base2Color;
typedef TypeStorage<struct gmt_color>::BaseM2Type BaseM2Color;
typedef TypeStorage<struct gmt_color>::BaseMT2Type BaseMT2Color;
typedef TypeStorage<struct gmt_color>::BaseMD2Type BaseMD2Color;
typedef TypeStorage<struct gmt_color>::BaseMTD2Type BaseMTD2Color;
// Definitions for ObjectGMTDash
template<> class TypeStorage<struct gmt_dash>: public gTypeStorage<struct gmt_dash,ObjectString,ObjectGMTDash> {};
typedef TypeStorage<struct gmt_dash>::Base2Type Base2Dash;
typedef TypeStorage<struct gmt_dash>::BaseM2Type BaseM2Dash;
typedef TypeStorage<struct gmt_dash>::BaseMT2Type BaseMT2Dash;
typedef TypeStorage<struct gmt_dash>::BaseMD2Type BaseMD2Dash;
typedef TypeStorage<struct gmt_dash>::BaseMTD2Type BaseMTD2Dash;
// Definitions for ObjectGMTPen
template<> class TypeStorage<struct gmt_pen>: public gTypeStorage<struct gmt_pen,ObjectList,ObjectString,ObjectReal,ObjectInt,ObjectGMTPen> {};
typedef TypeStorage<struct gmt_pen>::Base2Type Base2Pen;
typedef TypeStorage<struct gmt_pen>::BaseM2Type BaseM2Pen;
typedef TypeStorage<struct gmt_pen>::BaseMT2Type BaseMT2Pen;
typedef TypeStorage<struct gmt_pen>::BaseMD2Type BaseMD2Pen;
typedef TypeStorage<struct gmt_pen>::BaseMTD2Type BaseMTD2Pen;
// Definitions for ObjectGMTFont
template<> class TypeStorage<struct gmt_font>: public gTypeStorage<struct gmt_font,ObjectList,ObjectString,ObjectReal,ObjectInt,ObjectGMTFont> {};
typedef TypeStorage<struct gmt_font>::Base2Type Base2Font;
typedef TypeStorage<struct gmt_font>::BaseM2Type BaseM2Font;
typedef TypeStorage<struct gmt_font>::BaseMT2Type BaseMT2Font;
typedef TypeStorage<struct gmt_font>::BaseMD2Type BaseMD2Font;
typedef TypeStorage<struct gmt_font>::BaseMTD2Type BaseMTD2Font;
// Definitions for ObjectGMTLayer
template<> class TypeStorage<struct gmt_layer>: public gTypeStorage<struct gmt_layer,ObjectList,ObjectGMTLayer> {};
typedef TypeStorage<struct gmt_layer>::Base2Type Base2Layer;
typedef TypeStorage<struct gmt_layer>::BaseM2Type BaseM2Layer;
typedef TypeStorage<struct gmt_layer>::BaseMT2Type BaseMT2Layer;
typedef TypeStorage<struct gmt_layer>::BaseMD2Type BaseMD2Layer;
typedef TypeStorage<struct gmt_layer>::BaseMTD2Type BaseMTD2Layer;
using Base2NonNegD=DefaultConverter<Base2NonNeg>;
// Conversion from List to GMTRegion
/*

Loading…
Cancel
Save