summaryrefslogtreecommitdiff
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
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
-rw-r--r--project2/common/pch.hpp1
-rw-r--r--project2/common/variableConvert.cpp90
-rw-r--r--project2/common/variables.cpp68
-rw-r--r--project2/common/variables.h11
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