Added simple serialization library.
authorethereal <ethereal@ethv.net>
Mon, 11 Nov 2013 01:31:12 +0000 (18:31 -0700)
committerethereal <ethereal@ethv.net>
Mon, 11 Nov 2013 01:31:12 +0000 (18:31 -0700)
13 files changed:
COPYING
src/CMakeLists.txt
src/main.cpp
src/math/Quaternion.cpp
src/math/Quaternion.h
src/math/Vector.cpp
src/math/Vector.h
src/resource/XMLInterface.cpp
src/resource/XMLInterface.h
src/resource/XMLInterfaceMP.h [new file with mode: 0644]
src/resource/XMLInterfaceMacros.h [new file with mode: 0644]
src/resource/XMLInterfaceParse.h [new file with mode: 0644]
src/resource/XMLInterfaceSerialize.h [new file with mode: 0644]

diff --git a/COPYING b/COPYING
index 9cdec52..e2a7308 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -13,7 +13,7 @@ modification, are permitted provided that the following conditions are met:
 - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
-- Neither the name Kriti nor the names of its contributors may be used to
+- Neither the name Skeleton nor the names of its contributors may be used to
     endorse or promote products derived from this software without specific
     prior written permission.
 
index 5dcd184..6653f50 100644 (file)
@@ -1,6 +1,5 @@
 add_definitions(-Wextra -Wall -std=c++11)
 add_definitions(-g -DDEBUG)
-add_definitions(-Wno-unused-parameter)
 
 include_directories(. ${pugixmlInclude})
 
index 6ed8f40..5c5ad0d 100644 (file)
@@ -38,18 +38,14 @@ int main(int argc, char *argv[]) {
         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)");
+        auto v = Resource::XMLParse<Math::Vector>("(1,2,3)");
         std::cout << v.toString() << std::endl;
+        std::cout << Resource::XMLSerialize(v) << std::endl;
     }
 
+    std::cout << Resource::XMLSerialize(std::make_tuple(21, 2)) << std::endl;
+
     return 0;
 }
 
index 502aa60..3e1bcb0 100644 (file)
@@ -3,26 +3,6 @@
 #include "resource/XMLInterface.h"
 
 namespace Skeleton {
-
-#if 0
-template<>
-Math::Quaternion XMLParse<Math::Quaternion>(const std::string &from,
-    bool &worked) {
-    
-}
-
-template<>
-std::string XMLSerialize<Math::Quaternion>(const Math::Quaternion &from) {
-    Math::Vector axis;
-    double angle;
-
-    from.toAxisAngle(axis, angle);
-
-    return XMLSerialize<Math::Vector>(axis) + ","
-        + XMLSerialize<double>(angle);
-}
-#endif
-
 namespace Math {
 
 Quaternion::Quaternion(const Vector &axis, double angle) {
index a7d280e..089a46a 100644 (file)
@@ -4,6 +4,8 @@
 #include "Vector.h"
 #include "Matrix.h"
 
+#include "resource/XMLInterface.h"
+
 namespace Skeleton {
 namespace Math {
 
@@ -12,6 +14,9 @@ class Quaternion {
 private:
     double m_s;
     Vector m_v;
+
+    XML_INTERFACE2(m_v, m_s)
+    XML_AUTO_PARSE2(Quaternion)
 private:
     Quaternion(double s, Vector v) : m_s(s), m_v(v) {}
 public:
index bca0e1b..a1970ab 100644 (file)
@@ -6,25 +6,6 @@
 #include "resource/XMLInterface.h"
 
 namespace Skeleton {
-
-#if 0
-template<>
-Math::Vector XMLParse<Math::Vector>(const std::string &from, bool &worked) {
-    worked = false;
-
-    /*auto result = XMLParse<std::tuple<double,double,double>>(from, worked);*/
-    if(!worked) return Math::Vector();
-    /*return Math::Vector(std::get<0>(result), std::get<1>(result),
-        std::get<2>(result));*/
-}
-
-template<>
-std::string XMLSerialize<Math::Vector>(const Math::Vector &vector) {
-    /*return XMLSerialize<std::tuple<double,double,double>>(
-        std::tuple<double,double,double>(vector.x(), vector.y(), vector.z()));*/
-}
-#endif
-
 namespace Math {
 
 std::string Vector::toString() const {
index d66daba..c467b12 100644 (file)
@@ -15,7 +15,9 @@ class Vector {
 private:
     double m_x, m_y, m_z;
 
-    XML_INTERFACE_SIMPLE3(Vector, m_x, m_y, m_z)
+    XML_INTERFACE3(m_x, m_y, m_z)
+    XML_AUTO_SERIALIZE3(Vector, m_x, m_y, m_z)
+    XML_AUTO_PARSE3(Vector)
 public:
     Vector(double x = 0.0, double y = 0.0, double z = 0.0)
         : m_x(x), m_y(y), m_z(z) {}
index 4890464..d3bcbce 100644 (file)
@@ -4,6 +4,7 @@
 #include "XMLInterface.h"
 
 namespace Skeleton {
+namespace Resource {
 
 // int functions
 template<>
@@ -14,6 +15,11 @@ int XMLParse<int>(std::istringstream &from, bool &worked) {
     return value;
 }
 
+template<>
+void XMLSerialize<int>(std::ostringstream &into, const int &object) {
+    into << object;
+}
+
 // double functions
 template<>
 double XMLParse<double>(std::istringstream &from, bool &worked) {
@@ -23,6 +29,11 @@ double XMLParse<double>(std::istringstream &from, bool &worked) {
     return value;
 }
 
+template<>
+void XMLSerialize<double>(std::ostringstream &into, const double &object) {
+    into << object;
+}
+
 /*
 // std::string functions
 template<>
@@ -109,4 +120,5 @@ std::string XMLSerialize<double>(const double &from) {
 }
 */
 
+}  // namespace Resource
 }  // namespace Skeleton
index b1934ef..745c337 100644 (file)
@@ -3,190 +3,9 @@
 
 #include <iostream> // debugging
 
-#include <sstream>
-#include <tuple>
-#include <string>
-#include <type_traits>
+#include "XMLInterfaceMacros.h"
 
-#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>
-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(
-    std::istringstream &from, bool &worked) {
-
-    worked = false;
-    if(!from.good()) return T();
-
-    char next;
-    from >> next;
-    if(next != '[') return T();
-
-    if(from.peek() == ']') {
-        worked = true;
-        return T();
-    }
-    if(!from.good()) return T();
-
-    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();
-    }
-
-    if(!worked) return T();
-    return result;
-}
-
-template<std::size_t index, typename T>
-typename std::enable_if<index == std::tuple_size<T>::value, void>::type
-XMLParseTupleHelper(std::istringstream &from, bool &worked, T &result) {
-    // empty, nothing more to parse
-}
-
-template<std::size_t index, typename T>
-typename std::enable_if<index != std::tuple_size<T>::value, void>::type
-XMLParseTupleHelper(std::istringstream &from, bool &worked, T &result) {
-
-    std::get<index>(result) = XMLParse<
-        typename std::tuple_element<index, T>::type>(from, worked);
-
-    // if not last, expect a comma.
-    if(index+1 != std::tuple_size<T>::value) {
-        if(!from.good()) { worked = false; return; }
-        if(from.get() != ',') { worked = false; return; }
-    }
-    
-    XMLParseTupleHelper<index+1, T>(from, worked, result);
-}
-
-template<typename T>
-T XMLParseTupleHelper(std::istringstream &from, bool &worked) {
-    T result;
-
-    XMLParseTupleHelper<0, T>(from, worked, result);
-
-    return result;
-}
-
-// tuple specialization
-template<typename T>
-typename std::enable_if<MP::is_tuple<T>::value, T>::type XMLParse(
-    std::istringstream &from, bool &worked) {
-
-    worked = false;
-    if(!from.good()) return T();
-
-    char next;
-    from >> next;
-    if(next != '(') return T();
-
-    if(from.peek() == ')') {
-        worked = true;
-        return T();
-    }
-    if(!from.good()) return T();
-
-    return XMLParseTupleHelper<T>(from, worked);
-}
-
-// 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) {
-
-    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) {
-    bool worked = false;
-    return XMLParse<T>(from, worked);
-}
-
-}  // namespace Skeleton
+#include "XMLInterfaceParse.h"
+#include "XMLInterfaceSerialize.h"
 
 #endif
diff --git a/src/resource/XMLInterfaceMP.h b/src/resource/XMLInterfaceMP.h
new file mode 100644 (file)
index 0000000..6ebc874
--- /dev/null
@@ -0,0 +1,31 @@
+template<typename T>
+struct HasXMLInterface {
+private:
+    struct orig { int s_hasXMLInterface; };
+    struct next : T, orig {};
+
+    template<typename R, R> struct Check;
+
+    template<typename R> static char (&f(Check<int orig::*,
+        &R::s_hasXMLInterface>*))[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 HasXMLInterface<int> {
+    static const bool value = false;
+};
+
+template<>
+struct HasXMLInterface<double> {
+    static const bool value = false;
+};
+
+template<>
+struct HasXMLInterface<bool> {
+    static const bool value = false;
+};
diff --git a/src/resource/XMLInterfaceMacros.h b/src/resource/XMLInterfaceMacros.h
new file mode 100644 (file)
index 0000000..28e15e6
--- /dev/null
@@ -0,0 +1,34 @@
+#define XML_AUTO_PARSE2(type) \
+    static type XMLInterfaceParse( \
+        const XMLInterfaceType &data) { \
+        \
+        return type(std::get<0>(data), std::get<1>(data)); \
+    }
+
+#define XML_AUTO_PARSE3(type) \
+    static type XMLInterfaceParse( \
+        const XMLInterfaceType &data) { \
+        \
+        return type(std::get<0>(data), std::get<1>(data), std::get<2>(data)); \
+    }
+
+#define XML_AUTO_SERIALIZE3(type, name1, name2, name3) \
+    static XMLInterfaceType XMLInterfaceSerialize( \
+        const type &instance) { \
+        \
+        return std::make_tuple(instance.name1, instance.name2, instance.name3); \
+    }
+
+#define XML_INTERFACE_HEAD \
+    public: \
+    static const bool s_hasXMLInterface = true;
+
+#define XML_INTERFACE2(name1, name2) \
+    XML_INTERFACE_HEAD \
+    typedef std::tuple<decltype(name1), decltype(name2)> \
+        XMLInterfaceType;
+
+#define XML_INTERFACE3(name1, name2, name3) \
+    XML_INTERFACE_HEAD \
+    typedef std::tuple<decltype(name1), decltype(name2), decltype(name3)> \
+        XMLInterfaceType;
diff --git a/src/resource/XMLInterfaceParse.h b/src/resource/XMLInterfaceParse.h
new file mode 100644 (file)
index 0000000..fddc009
--- /dev/null
@@ -0,0 +1,145 @@
+#include <sstream>
+#include <type_traits>
+#include <tuple>
+
+#include "TemplateMP.h"
+#include "XMLInterfaceMP.h"
+
+namespace Skeleton {
+namespace Resource {
+
+// forward declarations
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && !HasXMLInterface<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
+    && HasXMLInterface<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(
+    std::istringstream &from, bool &worked) {
+
+    worked = false;
+    if(!from.good()) return T();
+
+    char next;
+    from >> next;
+    if(next != '[') return T();
+
+    if(from.peek() == ']') {
+        worked = true;
+        return T();
+    }
+    if(!from.good()) return T();
+
+    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();
+    }
+
+    if(!worked) return T();
+    return result;
+}
+
+template<std::size_t index, typename T>
+typename std::enable_if<index == std::tuple_size<T>::value, void>::type
+XMLParseTupleHelper(std::istringstream __attribute__((unused)) &from,
+    bool &worked, T __attribute__((unused)) &result) {
+    // empty, nothing more to parse
+    worked = true;
+}
+
+template<std::size_t index, typename T>
+typename std::enable_if<index != std::tuple_size<T>::value, void>::type
+XMLParseTupleHelper(std::istringstream &from, bool &worked, T &result) {
+
+    std::get<index>(result) = XMLParse<
+        typename std::tuple_element<index, T>::type>(from, worked);
+
+    // if not last, expect a comma.
+    if(index+1 != std::tuple_size<T>::value) {
+        if(!from.good()) { worked = false; return; }
+        if(from.get() != ',') { worked = false; return; }
+    }
+    
+    XMLParseTupleHelper<index+1, T>(from, worked, result);
+}
+
+template<typename T>
+T XMLParseTupleHelper(std::istringstream &from, bool &worked) {
+    T result;
+
+    XMLParseTupleHelper<0, T>(from, worked, result);
+
+    return result;
+}
+
+// tuple specialization
+template<typename T>
+typename std::enable_if<MP::is_tuple<T>::value, T>::type XMLParse(
+    std::istringstream &from, bool &worked) {
+
+    worked = false;
+    if(!from.good()) return T();
+
+    char next;
+    from >> next;
+    if(next != '(') return T();
+
+    if(from.peek() == ')') {
+        worked = true;
+        return T();
+    }
+    if(!from.good()) return T();
+
+    return XMLParseTupleHelper<T>(from, worked);
+}
+
+// simple interface specialization
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && HasXMLInterface<T>::value, T>::type
+    XMLParse(std::istringstream &from, bool &worked) {
+
+    return T::XMLInterfaceParse(
+        XMLParse<typename T::XMLInterfaceType>(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) {
+    bool worked = false;
+    return XMLParse<T>(from, worked);
+}
+
+}  // namespace Resource
+}  // namespace Skeleton
diff --git a/src/resource/XMLInterfaceSerialize.h b/src/resource/XMLInterfaceSerialize.h
new file mode 100644 (file)
index 0000000..d752b01
--- /dev/null
@@ -0,0 +1,98 @@
+#include <sstream>
+#include <type_traits>
+#include <tuple>
+
+namespace Skeleton {
+namespace Resource {
+
+// forward declarations
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && !HasXMLInterface<T>::value, void>::type XMLSerialize(
+        std::ostringstream &into, const T &object);
+
+template<typename T>
+typename std::enable_if<MP::is_vector<T>::value, void>::type XMLSerialize(
+    std::ostringstream &into, const T &object);
+
+template<typename T>
+typename std::enable_if<MP::is_tuple<T>::value, void>::type XMLSerialize(
+    std::ostringstream &into, const T &object);
+
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && HasXMLInterface<T>::value, void>::type
+    XMLSerialize(std::ostringstream &into, const T &object);
+
+// vector specialization
+template<typename T>
+typename std::enable_if<MP::is_vector<T>::value, void>::type XMLSerialize(
+    std::ostringstream &into, const T &object) {
+
+    into << '[';
+    for(typename T::size_type i = 0; i < object.size(); i ++) {
+        if(i != 0) into << ',';
+        XMLSerialize<typename T::value_type>(into, object[i]);
+    }
+    into << ']';
+}
+
+
+// start of tuple specialization
+template<std::size_t index, typename T>
+typename std::enable_if<index == std::tuple_size<T>::value, void>::type
+XMLSerializeTupleHelper(std::ostringstream __attribute__((unused)) &into,
+    const T __attribute__((unused)) &object) {
+    // empty, nothing more to do
+}
+
+template<std::size_t index, typename T>
+typename std::enable_if<index != std::tuple_size<T>::value, void>::type
+XMLSerializeTupleHelper(std::ostringstream &into, const T &object) {
+    // if not first, add a comma.
+    if(index != 0) {
+        into << ",";
+    }
+
+    XMLSerialize<typename std::tuple_element<index, T>::type>(
+        into, std::get<index>(object)
+    );
+    
+    XMLSerializeTupleHelper<index+1, T>(into, object);
+}
+
+template<typename T>
+void XMLSerializeTupleHelper(std::ostringstream &from, const T &object) {
+    XMLSerializeTupleHelper<0, T>(from, object);
+}
+
+// tuple specialization
+template<typename T>
+typename std::enable_if<MP::is_tuple<T>::value, void>::type XMLSerialize(
+    std::ostringstream &into, const T &object) {
+
+    into << '(';
+    XMLSerializeTupleHelper<T>(into, object);
+    into << ')';
+}
+
+// XML interface specialization
+template<typename T>
+typename std::enable_if<!MP::is_vector<T>::value && !MP::is_tuple<T>::value
+    && HasXMLInterface<T>::value, void>::type
+    XMLSerialize(std::ostringstream &into, const T &object) {
+
+    typename T::XMLInterfaceType result = object.XMLInterfaceSerialize(object);
+    XMLSerialize(into, result);
+}
+
+
+template<typename T>
+std::string XMLSerialize(const T &object) {
+    std::ostringstream ss;
+    XMLSerialize<T>(ss, object);
+    return ss.str();
+}
+
+}  // namespace Resource
+}  // namespace Skeleton