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 /project2/common/variableConvert.cpp | |
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
Diffstat (limited to 'project2/common/variableConvert.cpp')
-rw-r--r-- | project2/common/variableConvert.cpp | 90 |
1 files changed, 28 insertions, 62 deletions
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 { |