From d6617814762f5f034ef9f5fe722caf7343ae0563 Mon Sep 17 00:00:00 2001 From: randomdan Date: Tue, 27 Dec 2011 19:29:12 +0000 Subject: Much improved variable conversion and conversion caching for speed benefits --- project2/common/pch.hpp | 1 + project2/common/variableConvert.cpp | 90 ++++++++++++------------------------- project2/common/variables.cpp | 68 +++++++++------------------- project2/common/variables.h | 11 ++--- 4 files changed, 55 insertions(+), 115 deletions(-) diff --git a/project2/common/pch.hpp b/project2/common/pch.hpp index 85a7932..4150755 100644 --- a/project2/common/pch.hpp +++ b/project2/common/pch.hpp @@ -3,6 +3,7 @@ #define COMMON_PCH #include +#include #include #include #include diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp index a7ddca4..6237c26 100644 --- a/project2/common/variableConvert.cpp +++ b/project2/common/variableConvert.cpp @@ -5,28 +5,13 @@ #include #include -template -void -deleter(const void * t) -{ - delete static_cast(t); -} +#define CONVERTF(RT, CF, MF) \ + if (RT * v = boost::any_cast(&var->convertCache)) return v->MF(); \ + return boost::any_cast(&(var->convertCache = (RT)CF(r)))->MF(); -template -const T * -set(const VariableType * var, const T * t, VariableType::Freer f = deleter) -{ - if (var->freer) { var->freer(var->convertCache); } - var->convertCache = t; - var->freer = f; - return t; -} -template -const T * -set(const VariableType * var, const T * t) -{ - return ::set(var, t, deleter); -} +#define CONVERT(RT, CF) \ + if (RT * v = boost::any_cast(&var->convertCache)) return *v; \ + return *boost::any_cast(&(var->convertCache = (RT)CF(r))); SimpleMessage2Exception(InvalidConversionTo); @@ -42,17 +27,17 @@ class ConvertVisitorGlibUstring : public boost::static_visitor const Glib::ustring & operator()(const T & r) const { - return *::set(var, new Glib::ustring(boost::lexical_cast(r))); + CONVERT(const Glib::ustring, boost::lexical_cast); } private: const VariableType * var; @@ -63,17 +48,17 @@ class ConvertVisitorStdString : public boost::static_visitor const std::string & operator()(const T & r) const { - return *::set(var, new std::string(boost::lexical_cast(r))); + CONVERTF(const Glib::ustring, boost::lexical_cast, raw); } private: const VariableType * var; @@ -84,39 +69,17 @@ class ConvertVisitorCharStar : public boost::static_visitor { ConvertVisitorCharStar(const VariableType * v) : var(v) { } const char * operator()(const Glib::ustring & r) const { - return ::set(var, &r, NULL)->c_str(); + return r.c_str(); } const char * operator()(const boost::posix_time::ptime & r) const { - return ::set(var, new std::string(boost::posix_time::to_iso_extended_string(r)))->c_str(); + CONVERTF(const Glib::ustring, boost::posix_time::to_iso_extended_string, c_str); } const char * operator()(const Null &) const { - return ::set(var, NULL, NULL); + return NULL; } template const char * operator()(const T & r) const { - return ::set(var, new std::string(boost::lexical_cast(r)))->c_str(); - } - private: - const VariableType * var; -}; -// Convert to unsigned char * (with std::basic_string storage / std::string) -class ConvertVisitorUCharStar : public boost::static_visitor { - public: - ConvertVisitorUCharStar(const VariableType * v) : var(v) { - } - const unsigned char * operator()(const Glib::ustring & r) const { - return reinterpret_cast(set(var, &r, NULL)->c_str()); - } - const unsigned char * operator()(const boost::posix_time::ptime & r) const { - return reinterpret_cast( - ::set(var, new std::string(boost::posix_time::to_iso_extended_string(r)))->c_str()); - } - const unsigned char * operator()(const Null &) const { - return ::set(var, NULL, NULL); - } - template - const unsigned char * operator()(const T & r) const { - return ::set(var, new std::basic_string(boost::lexical_cast >(r)))->c_str(); + CONVERTF(const Glib::ustring, boost::lexical_cast, c_str); } private: const VariableType * var; @@ -128,7 +91,7 @@ class ConvertVisitor : public boost::static_visitor { ConvertVisitor(const VariableType * v) : var(v) { } DestType operator()(const Glib::ustring & r) const { - return boost::lexical_cast(r); + CONVERT(DestType, boost::lexical_cast); } DestType operator()(const boost::posix_time::ptime &) const { throw InvalidConversionTo(typeid(DestType).name(), ""); @@ -141,7 +104,7 @@ class ConvertVisitor : public boost::static_visitor { } template DestType operator()(const T & r) const { - return boost::numeric_cast(r); + CONVERT(DestType, boost::numeric_cast); } private: const VariableType * var; @@ -152,7 +115,7 @@ class ConvertVisitorDateTime : public boost::static_visitor); + CONVERT(const boost::posix_time::ptime, boost::posix_time::time_from_string); } const boost::posix_time::ptime & operator()(const boost::posix_time::ptime & r) const { return r; @@ -172,11 +135,8 @@ class ConvertVisitorBool : public boost::static_visitor { public: ConvertVisitorBool(const VariableType * v) : var(v) { } - bool operator()(const Glib::ustring & s) const { - const char * str = s.c_str(); - if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0) return true; - if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0 || strcasecmp(str, "off") == 0) return false; - throw InvalidConversionTo("bool", s); + bool operator()(const Glib::ustring & r) const { + CONVERT(bool, fromStr); } bool operator()(const boost::posix_time::ptime &) const { throw InvalidConversionTo("bool", ""); @@ -189,6 +149,12 @@ class ConvertVisitorBool : public boost::static_visitor { return (t != 0); } private: + static bool fromStr(const Glib::ustring & s) { + const char * str = s.c_str(); + if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0) return true; + if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0 || strcasecmp(str, "off") == 0) return false; + throw InvalidConversionTo("bool", s); + } const VariableType * var; }; VariableType::operator const Glib::ustring &() const @@ -205,7 +171,7 @@ VariableType::operator const char *() const } VariableType::operator const unsigned char *() const { - return boost::apply_visitor(ConvertVisitorUCharStar(this), *this); + return reinterpret_cast(boost::apply_visitor(ConvertVisitorCharStar(this), *this)); } VariableType::operator int32_t() const { diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp index 6b2d7c9..8b4ce38 100644 --- a/project2/common/variables.cpp +++ b/project2/common/variables.cpp @@ -70,17 +70,24 @@ SimpleMessageException(DateParseError); VariableType VariableType::make(const Glib::ustring & src, const VT_typeID format) { + VariableType vt; switch (format) { default: case DefaultType: case String: - return src; + vt = src; + return vt; + case Nul: + return Null(); case Bool: - return boost::lexical_cast(src); + vt = boost::lexical_cast(src); + break; case Int: - return boost::lexical_cast(src); + vt = boost::lexical_cast(src); + break; case Float: - return boost::lexical_cast(src); + vt = boost::lexical_cast(src); + break; case DateTime: { struct tm tm; @@ -92,46 +99,36 @@ VariableType::make(const Glib::ustring & src, const VT_typeID format) __PRETTY_FUNCTION__, src.c_str(), "%FT%T", e); throw DateParseError(src); } - return boost::posix_time::ptime_from_tm(tm); + vt = boost::posix_time::ptime_from_tm(tm); } - case Nul: - return Null(); + break; } + vt.convertCache = src; + return vt; } -VariableType::VariableType() : - _VT(), - convertCache(NULL), - freer(NULL) +VariableType::VariableType() { } #define VTCONS(Source) \ VariableType::VariableType(const Source & t) : \ - _VT(t), \ - convertCache(NULL), \ - freer(NULL) \ + _VT(t) \ { \ } #define VTCONSD(Source, Store) \ VariableType::VariableType(const Source & t) : \ - _VT(Store(t)), \ - convertCache(NULL), \ - freer(NULL) \ + _VT(Store(t)) \ { \ } #define VTCONSC(Source, Store, Cast) \ VariableType::VariableType(const Source & t) : \ - _VT(Store((Cast)t)), \ - convertCache(NULL), \ - freer(NULL) \ + _VT(Store((Cast)t)) \ { \ } #define VTCONSN(Source, Store) \ VariableType::VariableType(const Source & t) : \ - _VT(boost::numeric_cast(t)), \ - convertCache(NULL), \ - freer(NULL) \ + _VT(boost::numeric_cast(t)) \ { \ } @@ -152,35 +149,14 @@ VTCONSD(char * const, Glib::ustring); VTCONSC(unsigned char * const, Glib::ustring, const char * const); VariableType::VariableType(const struct tm & vt) : - _VT(boost::posix_time::ptime_from_tm(vt)), - convertCache(NULL), - freer(NULL) + _VT(boost::posix_time::ptime_from_tm(vt)) { } VariableType::VariableType(const VariableType & vt) : _VT(*((const _VT *)&vt)), - convertCache(NULL), - freer(NULL) -{ -} - -VariableType::~VariableType() -{ - if (freer && convertCache) { - freer(convertCache); - } -} - -void -VariableType::operator=(const VariableType & vt) + convertCache(vt.convertCache) { - if (freer && convertCache) { - freer(convertCache); - } - freer = NULL; - convertCache = NULL; - _VT::operator=(*((const _VT *)&vt)); } template diff --git a/project2/common/variables.h b/project2/common/variables.h index 2c1f15d..2757ade 100644 --- a/project2/common/variables.h +++ b/project2/common/variables.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -54,7 +55,6 @@ typedef boost::variant< class VariableType : public _VT { public: - typedef void(*Freer)(const void*); VariableType(const unsigned char * const & t); VariableType(const char * const & t); VariableType(const std::string &); @@ -73,11 +73,10 @@ class VariableType : public _VT { VariableType(const double &); VariableType(); VariableType(const VariableType &); - ~VariableType(); + static VariableType make(const Glib::ustring & src, const VT_typeID format = DefaultType); static VT_typeID getTypeFromName(const std::string & src); - void operator=(const VariableType &); bool operator<(const VariableType &) const; operator const Glib::ustring &() const; @@ -92,10 +91,8 @@ class VariableType : public _VT { template T as() const { return *this; } template const T * get() const { return boost::get(this); } - private: - template friend const T * set(const VariableType * var, const T * t, Freer); - mutable const void * convertCache; - mutable Freer freer; + typedef boost::any ConvertCache; + mutable ConvertCache convertCache; }; /// Base class for Project2 variable accessors -- cgit v1.2.3