summaryrefslogtreecommitdiff
path: root/project2/common/variableConvert.cpp
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-27 19:29:12 +0000
committerrandomdan <randomdan@localhost>2011-12-27 19:29:12 +0000
commit4a534c8a67a2da3deb8cf3de73ce646bff2e018f (patch)
treef532e83aea1dd030376ffbd91c511f9d4ac75798 /project2/common/variableConvert.cpp
parentAdd type safety to XML documents (diff)
downloadproject2-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.cpp90
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
{