Implemented simple serialization interface.
authorethereal <ethereal@ethv.net>
Sun, 10 Nov 2013 23:51:15 +0000 (16:51 -0700)
committerethereal <ethereal@ethv.net>
Sun, 10 Nov 2013 23:51:15 +0000 (16:51 -0700)
Next up: not-so-simple serialization interface.

src/main.cpp
src/math/Vector.h
src/resource/XMLInterface.cpp
src/resource/XMLInterface.h

index b17488c..6ed8f40 100644 (file)
@@ -7,13 +7,15 @@
 #include "resource/Registry.h"
 #include "TemplateMP.h"
 
+#include "math/Vector.h"
+
 int main(int argc, char *argv[]) {
     using namespace Skeleton;
 
     auto configXML = Resource::Registry::get<Resource::XML>("data/config.xml");
     Resource::Registry::alias<Resource::XML>("data/config.xml", "config");
 
-
+#if 0
     {
         auto v = XMLParse<std::vector<int>>("[2,3,3,4]");
         std::cout << v.size() << std::endl;
@@ -35,6 +37,18 @@ int main(int argc, char *argv[]) {
         std::cout << "\t\t" << std::get<0>(std::get<1>(v)) << std::endl;
         std::cout << "\t\t" << std::get<1>(std::get<1>(v)) << std::endl;
     }
+#endif
+
+    {
+        
+        std::cout << HasSimpleInterface<std::string>::value << std::endl;
+        std::cout << HasSimpleInterface<Math::Vector>::value << std::endl;
+        std::cout << HasSimpleInterface<std::vector<int>>::value << std::endl;
+        std::cout << HasSimpleInterface<int>::value << std::endl;
+
+        auto v = XMLParse<Math::Vector>("(1,2,3)");
+        std::cout << v.toString() << std::endl;
+    }
 
     return 0;
 }
index 3ff8b62..d66daba 100644 (file)
@@ -6,12 +6,16 @@
 
 #include "Constants.h"
 
+#include "resource/XMLInterface.h"
+
 namespace Skeleton {
 namespace Math {
 
 class Vector {
 private:
     double m_x, m_y, m_z;
+
+    XML_INTERFACE_SIMPLE3(Vector, m_x, m_y, m_z)
 public:
     Vector(double x = 0.0, double y = 0.0, double z = 0.0)
         : m_x(x), m_y(y), m_z(z) {}
index 38f4f0a..4890464 100644 (file)
@@ -14,6 +14,15 @@ int XMLParse<int>(std::istringstream &from, bool &worked) {
     return value;
 }
 
+// double functions
+template<>
+double XMLParse<double>(std::istringstream &from, bool &worked) {
+    double value;
+    worked = (from >> value);
+
+    return value;
+}
+
 /*
 // std::string functions
 template<>
index ab68f30..b1934ef 100644 (file)
 
 #include "TemplateMP.h"
 
+#define XML_INTERFACE_SIMPLE3(type, name1, name2, name3) \
+    public: \
+    static const bool s_hasSimpleXMLParseInterface = false; \
+    typedef std::tuple<decltype(name1), decltype(name2), decltype(name3)> \
+        XMLSimpleParseInterfaceType; \
+    static type XMLSimpleParseConstructor( \
+        const XMLSimpleParseInterfaceType &data) { \
+        \
+        return type(std::get<0>(data), std::get<1>(data), std::get<2>(data)); \
+    }
+
 namespace Skeleton {
 
 template<typename T>
-typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value,
-    T>::type XMLParse(std::istringstream &from, bool &worked);
+struct HasSimpleInterface {
+private:
+    struct orig { int s_hasSimpleXMLParseInterface; };
+    struct next : T, orig {};
+
+    template<typename R, R> struct Check;
+
+    template<typename R> static char (&f(Check<int orig::*,
+        &R::s_hasSimpleXMLParseInterface>*))[1];
+    template<typename R> static char (&f(...))[2];
+
+public:
+    static const bool value = sizeof(f<next>(0)) == 2;
+};
+
+// need to provide overloads for primitive types
+template<>
+struct HasSimpleInterface<int> {
+    static const bool value = false;
+};
+
+template<>
+struct HasSimpleInterface<double> {
+    static const bool value = false;
+};
+
+template<>
+struct HasSimpleInterface<bool> {
+    static const bool value = false;
+};
+
+
+// forward declarations
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && !HasSimpleInterface<T>::value, T>::type XMLParse(
+        std::istringstream &from, bool &worked);
+
 template<typename T>
 typename std::enable_if<MP::is_vector<T>::value, T>::type XMLParse(
     std::istringstream &from, bool &worked);
+
 template<typename T>
 typename std::enable_if<MP::is_tuple<T>::value, T>::type XMLParse(
     std::istringstream &from, bool &worked);
 
-    
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && HasSimpleInterface<T>::value, typename T::XMLSimpleSerializedType>::type
+    XMLParse(std::istringstream &from, bool &worked);
+
 // vector specialization
 template<typename T>
 typename std::enable_if<MP::is_vector<T>::value, T>::type XMLParse(
@@ -110,40 +162,29 @@ typename std::enable_if<MP::is_tuple<T>::value, T>::type XMLParse(
     if(!from.good()) return T();
 
     return XMLParseTupleHelper<T>(from, worked);
+}
 
-    #if 0
-    T result;
-
-    while(from.good()) {
-        /*result.push_back(
-            XMLParse<typename T::value_type>(from, worked)
-        );*/
-        if(!worked) return T();
-
-        if(!from.good()) { worked = false; break; }
-
-        if(from.peek() == ')') { from.get(); worked = true; break; }
-        if(from.peek() != ',') break;
-        else from.get();
-    }
+// simple interface specialization
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && HasSimpleInterface<T>::value, T>::type
+    XMLParse(std::istringstream &from, bool &worked) {
 
-    if(!worked) return T();
-    return result;
-    #endif
+    return T::XMLSimpleParseConstructor(
+        XMLParse<typename T::XMLSimpleParseInterfaceType>(from, worked));
 }
 
-
 template<typename T>
 T XMLParse(const std::string &from, bool &worked) {
     std::istringstream ss(from);
+
     return XMLParse<T>(ss, worked);
 }
 
 template<typename T>
 T XMLParse(const std::string &from) {
-    std::istringstream ss(from);
     bool worked = false;
-    return XMLParse<T>(ss, worked);
+    return XMLParse<T>(from, worked);
 }
 
 }  // namespace Skeleton