diff options
author | randomdan <randomdan@localhost> | 2011-12-27 19:29:12 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-12-27 19:29:12 +0000 |
commit | 4a534c8a67a2da3deb8cf3de73ce646bff2e018f (patch) | |
tree | f532e83aea1dd030376ffbd91c511f9d4ac75798 | |
parent | Add type safety to XML documents (diff) | |
download | project2-4a534c8a67a2da3deb8cf3de73ce646bff2e018f.tar.bz2 project2-4a534c8a67a2da3deb8cf3de73ce646bff2e018f.tar.xz project2-4a534c8a67a2da3deb8cf3de73ce646bff2e018f.zip |
Much improved variable conversion and conversion caching for speed benefits
-rw-r--r-- | project2/common/pch.hpp | 1 | ||||
-rw-r--r-- | project2/common/variableConvert.cpp | 90 | ||||
-rw-r--r-- | project2/common/variables.cpp | 68 | ||||
-rw-r--r-- | 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 <algorithm> +#include <boost/any.hpp> #include <boost/bind.hpp> #include <boost/filesystem/path.hpp> #include <boost/foreach.hpp> 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 <boost/numeric/conversion/cast.hpp> #include <boost/date_time/posix_time/posix_time.hpp> -template <typename T> -void -deleter(const void * t) -{ - delete static_cast<const T *>(t); -} +#define CONVERTF(RT, CF, MF) \ + if (RT * v = boost::any_cast<RT>(&var->convertCache)) return v->MF(); \ + return boost::any_cast<RT>(&(var->convertCache = (RT)CF(r)))->MF(); -template <typename T> -const T * -set(const VariableType * var, const T * t, VariableType::Freer f = deleter<T>) -{ - if (var->freer) { var->freer(var->convertCache); } - var->convertCache = t; - var->freer = f; - return t; -} -template <typename T> -const T * -set(const VariableType * var, const T * t) -{ - return ::set(var, t, deleter<T>); -} +#define CONVERT(RT, CF) \ + if (RT * v = boost::any_cast<RT>(&var->convertCache)) return *v; \ + return *boost::any_cast<RT>(&(var->convertCache = (RT)CF(r))); SimpleMessage2Exception(InvalidConversionTo); @@ -42,17 +27,17 @@ class ConvertVisitorGlibUstring : public boost::static_visitor<const Glib::ustri ConvertVisitorGlibUstring(const VariableType * v) : var(v) { } const Glib::ustring & operator()(const Glib::ustring & r) const { - return *::set(var, &r, NULL); + return r; } const Glib::ustring & operator()(const boost::posix_time::ptime & r) const { - return *::set(var, new Glib::ustring(boost::posix_time::to_iso_extended_string(r))); + CONVERT(const Glib::ustring, boost::posix_time::to_iso_extended_string); } const Glib::ustring & operator()(const Null &) const { throw NullVariable(); } template <typename T> const Glib::ustring & operator()(const T & r) const { - return *::set(var, new Glib::ustring(boost::lexical_cast<Glib::ustring>(r))); + CONVERT(const Glib::ustring, boost::lexical_cast<Glib::ustring>); } private: const VariableType * var; @@ -63,17 +48,17 @@ class ConvertVisitorStdString : public boost::static_visitor<const std::string & ConvertVisitorStdString(const VariableType * v) : var(v) { } const std::string & operator()(const Glib::ustring & r) const { - return *::set(var, new std::string(r)); + return r.raw(); } const std::string & operator()(const boost::posix_time::ptime & r) const { - return *::set(var, new std::string(boost::posix_time::to_iso_extended_string(r))); + CONVERTF(const Glib::ustring, boost::posix_time::to_iso_extended_string, raw); } const std::string & operator()(const Null &) const { throw NullVariable(); } template <typename T> const std::string & operator()(const T & r) const { - return *::set(var, new std::string(boost::lexical_cast<std::string>(r))); + CONVERTF(const Glib::ustring, boost::lexical_cast<Glib::ustring>, raw); } private: const VariableType * var; @@ -84,39 +69,17 @@ class ConvertVisitorCharStar : public boost::static_visitor<const char *> { 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<char>(var, NULL, NULL); + return NULL; } template <typename T> const char * operator()(const T & r) const { - return ::set(var, new std::string(boost::lexical_cast<std::string>(r)))->c_str(); - } - private: - const VariableType * var; -}; -// Convert to unsigned char * (with std::basic_string<unsigned char> storage / std::string) -class ConvertVisitorUCharStar : public boost::static_visitor<const unsigned char *> { - public: - ConvertVisitorUCharStar(const VariableType * v) : var(v) { - } - const unsigned char * operator()(const Glib::ustring & r) const { - return reinterpret_cast<const unsigned char *>(set(var, &r, NULL)->c_str()); - } - const unsigned char * operator()(const boost::posix_time::ptime & r) const { - return reinterpret_cast<const unsigned char *>( - ::set(var, new std::string(boost::posix_time::to_iso_extended_string(r)))->c_str()); - } - const unsigned char * operator()(const Null &) const { - return ::set<unsigned char>(var, NULL, NULL); - } - template <typename T> - const unsigned char * operator()(const T & r) const { - return ::set(var, new std::basic_string<unsigned char>(boost::lexical_cast<std::basic_string<unsigned char> >(r)))->c_str(); + CONVERTF(const Glib::ustring, boost::lexical_cast<Glib::ustring>, c_str); } private: const VariableType * var; @@ -128,7 +91,7 @@ class ConvertVisitor : public boost::static_visitor<DestType> { ConvertVisitor(const VariableType * v) : var(v) { } DestType operator()(const Glib::ustring & r) const { - return boost::lexical_cast<DestType>(r); + CONVERT(DestType, boost::lexical_cast<DestType>); } DestType operator()(const boost::posix_time::ptime &) const { throw InvalidConversionTo(typeid(DestType).name(), "<Date Time>"); @@ -141,7 +104,7 @@ class ConvertVisitor : public boost::static_visitor<DestType> { } template <typename T> DestType operator()(const T & r) const { - return boost::numeric_cast<DestType>(r); + CONVERT(DestType, boost::numeric_cast<DestType>); } private: const VariableType * var; @@ -152,7 +115,7 @@ class ConvertVisitorDateTime : public boost::static_visitor<const boost::posix_t ConvertVisitorDateTime(const VariableType * v) : var(v) { } const boost::posix_time::ptime & operator()(const Glib::ustring & r) const { - return *::set(var, new boost::posix_time::ptime(boost::posix_time::time_from_string(r)), deleter<boost::posix_time::ptime>); + 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<bool> { 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", "<Date time>"); @@ -189,6 +149,12 @@ class ConvertVisitorBool : public boost::static_visitor<bool> { 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<const unsigned char *>(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<bool>(src); + vt = boost::lexical_cast<bool>(src); + break; case Int: - return boost::lexical_cast<int64_t>(src); + vt = boost::lexical_cast<int64_t>(src); + break; case Float: - return boost::lexical_cast<double>(src); + vt = boost::lexical_cast<double>(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<Store>(t)), \ - convertCache(NULL), \ - freer(NULL) \ + _VT(boost::numeric_cast<Store>(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 <class S> 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 <boost/intrusive_ptr.hpp> #include <boost/optional.hpp> +#include <boost/any.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <stdint.h> #include <glibmm/ustring.h> @@ -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 <typename T> T as() const { return *this; } template <typename T> const T * get() const { return boost::get<T>(this); } - private: - template <typename T> 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 |