summaryrefslogtreecommitdiff
path: root/project2/common/variableConvert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'project2/common/variableConvert.cpp')
-rw-r--r--project2/common/variableConvert.cpp197
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);
+}