diff options
Diffstat (limited to 'project2/common/variableConvert.cpp')
-rw-r--r-- | project2/common/variableConvert.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp new file mode 100644 index 0000000..b144175 --- /dev/null +++ b/project2/common/variableConvert.cpp @@ -0,0 +1,197 @@ +#include "variables.h" +#include "exceptions.h" +#include <boost/lexical_cast.hpp> +#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); +} + +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>); +} + +SimpleMessageException(InvalidConversionTo); + +class NullVariable : std::runtime_error { + public: + NullVariable() : std::runtime_error("Variable has null value where one is required") { + } +}; + +// Convert to Glib::ustring +class ConvertVisitorGlibUstring : public boost::static_visitor<const Glib::ustring &> { + public: + ConvertVisitorGlibUstring(const VariableType * v) : var(v) { + } + const Glib::ustring & operator()(const Glib::ustring & r) const { + return *::set(var, &r, NULL); + } + 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))); + } + 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))); + } + private: + const VariableType * var; +}; +// Convert to STL std::string +class ConvertVisitorStdString : public boost::static_visitor<const std::string &> { + public: + ConvertVisitorStdString(const VariableType * v) : var(v) { + } + const std::string & operator()(const Glib::ustring & r) const { + return *::set(var, new std::string(r)); + } + 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))); + } + 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))); + } + private: + const VariableType * var; +}; +// Convert to char * (with std::string storage) +class ConvertVisitorCharStar : public boost::static_visitor<const char *> { + public: + ConvertVisitorCharStar(const VariableType * v) : var(v) { + } + const char * operator()(const Glib::ustring & r) const { + return ::set(var, &r, NULL)->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(); + } + const char * operator()(const Null &) const { + return ::set<char>(var, NULL, 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(); + } + private: + const VariableType * var; +}; +// Convert to generic type +template <typename DestType> +class ConvertVisitor : public boost::static_visitor<DestType> { + public: + ConvertVisitor(const VariableType * v) : var(v) { + } + DestType operator()(const Glib::ustring & r) const { + return boost::lexical_cast<DestType>(r); + } + DestType operator()(const boost::posix_time::ptime &) const { + throw InvalidConversionTo(typeid(DestType).name()); + } + DestType operator()(const Null &) const { + throw NullVariable(); + } + template <typename T> + DestType operator()(const T & r) const { + return boost::numeric_cast<DestType>(r); + } + private: + const VariableType * var; +}; +// Convert to ptime +class ConvertVisitorDateTime : public boost::static_visitor<const boost::posix_time::ptime &> { + public: + 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>); + } + const boost::posix_time::ptime & operator()(const boost::posix_time::ptime & r) const { + return r; + } + const boost::posix_time::ptime & operator()(const Null &) const { + throw NullVariable(); + } + template <typename T> + const boost::posix_time::ptime & operator()(const T &) const { + throw InvalidConversionTo("DateTime"); + } + private: + const VariableType * var; +}; +VariableType::operator const Glib::ustring &() const +{ + return boost::apply_visitor(ConvertVisitorGlibUstring(this), *this); +} +VariableType::operator const std::string &() const +{ + return boost::apply_visitor(ConvertVisitorStdString(this), *this); +} +VariableType::operator const char *() const +{ + return boost::apply_visitor(ConvertVisitorCharStar(this), *this); +} +VariableType::operator const unsigned char *() const +{ + return boost::apply_visitor(ConvertVisitorUCharStar(this), *this); +} +VariableType::operator int32_t() const +{ + return boost::apply_visitor(ConvertVisitor<int32_t>(this), *this); +} +VariableType::operator int64_t() const +{ + return boost::apply_visitor(ConvertVisitor<int64_t>(this), *this); +} +VariableType::operator double() const +{ + return boost::apply_visitor(ConvertVisitor<double>(this), *this); +} +VariableType::operator const boost::posix_time::ptime &() const +{ + return boost::apply_visitor(ConvertVisitorDateTime(this), *this); +} |