diff --git a/Serializing/test.cpp b/Serializing/test.cpp index e0098f1..2f7d840 100644 --- a/Serializing/test.cpp +++ b/Serializing/test.cpp @@ -8,11 +8,65 @@ #include +// Some basic types that should build serializable structures from template -using Array = std::vector; -using String = std::string; -using Integer32 = int32_t; +using Array = std::vector; +using Boolean = bool; +using Byte = uint8_t; +using Char = int8_t; +using Unsigned32 = uint32_t; +using Unsigned64 = uint64_t; +using Integer32 = int32_t; +using Integer64 = int64_t; +using Float32 = float; +using Float64 = double; +using String = std::string; +// discourage 16bit types, CPUs aren't so efficient at these +// TODO: enums +/* + + about enums: + + Looks like C++17 might make reflection of enums nice. + http://aantron.github.io/better-enums/demo/C++17ReflectionProposal.html + In the mean time, something like this gets close with the use of an ugly macro where the enums are declared + however it provides similar syntax to what C++17 may have for using the reflection + http://melpon.org/wandbox/permlink/QelcwZNLi4gIx8Ux + + */ + +struct EnumBaseValue +{ + Integer32 id; + String name; +}; + + +struct EnumBase +{ + String name; + Array values; +}; + +#if 0 + +#if 1 +template +void Visit(V& v, T& var, typename V::Visit(T&))//, typename std::enable_if< ! std::is_function< decltype(T::Visit)(V&) >::value , T >::type* = 0 ) +// typename std::enable_if< false /* !std::is_function::value*/ >::type +//void Visit(V& v, T& var, typename std::enable_if< std::is_function::type , T >::type* = 0 ) +{ + v.Visit(var); +} +#endif + +template +void Visit(V& v, T& var) // , typename T::Visit) +//, typename std::enable_if< std::is_function< decltype(T::Visit)(V&) >::value , T >::type* = 0 ) +{ + var.Visit(v); +} template void Visit(V& v, Integer32& i) @@ -32,13 +86,7 @@ v.Visit(arr); } -template -void Visit(V& v, const char* /*name*/, T& var) -{ - //v.Enter(name); - var.Visit(v); - //v.Exit(name); -} +#endif class XMLSerializerVisitor @@ -105,10 +153,17 @@ void Visit(const char* name, T& var) { Enter(name); - ::Visit(*this, var); + //::Visit(*this, var); + Visit(var); Exit(name); } + template + void Visit(T& var) + { + var.Visit(*this); + } + std::string& Output() { output += "\n"; @@ -203,7 +258,7 @@ var = input.substr(offset, newLineOff-offset); offset = newLineOff; } - +/* template void Visit(const char* name, T& var) { @@ -211,6 +266,20 @@ ::Visit(*this, var); Exit(name); } + */ + template + void Visit(const char* name, T& var) + { + Enter(name); + Visit(var); + Exit(name); + } + + template + void Visit(T& var) + { + var.Visit(*this); + } private: std::string input; @@ -276,7 +345,14 @@ lastDepth = depth; output += indent(depth) + quoted(name) + " : "; - ::Visit(*this, var); + // ::Visit(*this, var); + Visit(var); + } + + template + void Visit(T& var) + { + var.Visit(*this); } std::string& Output() @@ -405,7 +481,8 @@ assert(str == quoted(name)); ParseString(str); // gets the ':' assert(str == ":"); - ::Visit(*this, var); + // ::Visit(*this, var); + Visit(var); int oldOffset = offset; ParseString(str); // gets the ',' if there @@ -413,6 +490,12 @@ offset = oldOffset; } + template + void Visit(T& var) + { + var.Visit(*this); + } + private: std::string input; int offset = 0; @@ -433,6 +516,16 @@ struct Person { + Boolean m_bool; + Byte m_uint8; + Char m_int8; + Unsigned32 m_uint32; + Unsigned64 m_uint64; + Integer32 m_int32; + Integer64 m_int64; + Float32 m_flt32; + Float64 m_flt64; + Integer32 id; String name; Array email; @@ -454,7 +547,106 @@ }; +/* +struct Employer +{ + String name; + +}; +*/ +/* +struct Property +{ + Property() : m_type(PT_Invalid) {} + ~Property() {} + + explicit Property(Boolean a_bool ) : m_type(PT_Boolean ) { m_basicType.m_bool = a_bool ; } + explicit Property(Byte a_uint8 ) : m_type(PT_Byte ) { m_basicType.m_uint8 = a_uint8 ; } + explicit Property(Char a_int8 ) : m_type(PT_Char ) { m_basicType.m_int8 = a_int8 ; } + explicit Property(Unsigned32 a_uint32) : m_type(PT_Unsigned32) { m_basicType.m_uint32 = a_uint32; } + explicit Property(Unsigned64 a_uint64) : m_type(PT_Unsigned64) { m_basicType.m_uint64 = a_uint64; } + explicit Property(Integer32 a_int32 ) : m_type(PT_Integer32 ) { m_basicType.m_int32 = a_int32 ; } + explicit Property(Integer64 a_int64 ) : m_type(PT_Integer64 ) { m_basicType.m_int64 = a_int64 ; } + explicit Property(Float32 a_flt32 ) : m_type(PT_Float32 ) { m_basicType.m_flt32 = a_flt32 ; } + explicit Property(Float64 a_flt64 ) : m_type(PT_Float64 ) { m_basicType.m_flt64 = a_flt64 ; } + explicit Property(const Array& a_array ) : m_type(PT_Array ) { m_array = a_array ; } + explicit Property(const String& a_string) : m_type(PT_String) { m_string = a_string; } + + enum PropertyType + { + // Uninitialize state + PT_Invalid = 0, + // Basic types + PT_Boolean = 1, + PT_Byte = 2, + PT_Char = 3, + PT_Unsigned32 = 4, + PT_Unsigned64 = 5, + PT_Integer32 = 6, + PT_Integer64 = 7, + PT_Float32 = 8, + PT_Float64 = 9, + // Complex types + PT_Array = 10, + PT_String = 11, + }; + + PropertyType m_type; + + union { + Boolean m_bool; + Byte m_uint8; + Char m_int8; + Unsigned32 m_uint32; + Unsigned64 m_uint64; + Integer32 m_int32; + Integer64 m_int64; + Float32 m_flt32; + Float64 m_flt64; + } m_basicType; + + Array m_array; + String m_string; + + // This can do both the serializing and de-serializing + // This might be good to have generated, but possibly being more explicit could be better too + // Also note the members could be private and this will still work + template + void Visit(V& v) + { + v.Enter("Property"); + Integer32 t = m_type; + v.Visit("type", t); + switch (m_type) + { + case PT_Boolean: + v.Visit("value", m_basicType.m_bool); break; + case PT_Byte: + v.Visit("value", m_basicType.m_uint8); break; + case PT_Char: + v.Visit("value", m_basicType.m_int8); break; + case PT_Unsigned32: + v.Visit("value", m_basicType.m_uint32); break; + case PT_Unsigned64: + v.Visit("value", m_basicType.m_uint64); break; + case PT_Integer32: + v.Visit("value", m_basicType.m_int32); break; + case PT_Integer64: + v.Visit("value", m_basicType.m_int64); break; + case PT_Float32: + v.Visit("value", m_basicType.m_flt32); break; + case PT_Float64: + v.Visit("value", m_basicType.m_flt64); break; + case PT_Array: + v.Visit("value", m_array); break; + case PT_String: + v.Visit("value", m_string); break; + } + v.Exit("Property"); + } +}; +*/ int main(int argc, char* argv[]) @@ -470,7 +662,7 @@ a.phoneNumbers.push_back("123555"); XMLSerializerVisitor serializer; - Visit(serializer, "personA", a); + serializer.Visit(a); printf("%s", serializer.Output().c_str()); input = serializer.Output(); } @@ -479,11 +671,11 @@ Person b; XMLDeserializerVisitor deserializer(input); - Visit(deserializer, "personB", b); + deserializer.Visit(b); { XMLSerializerVisitor serializer; - Visit(serializer, "personB", b); + serializer.Visit(b); printf("%s", serializer.Output().c_str()); } } @@ -498,7 +690,7 @@ a.phoneNumbers.push_back("123555"); JsonSerializerVisitor serializer; - Visit(serializer, "personA", a); + serializer.Visit(a); printf("%s", serializer.Output().c_str()); input = serializer.Output(); } @@ -507,14 +699,29 @@ Person b; JsonDeserializerVisitor deserializer(input); - Visit(deserializer, "personB", b); + deserializer.Visit(b); { JsonSerializerVisitor serializer; - Visit(serializer, "personB", b); + serializer.Visit(b); printf("%s", serializer.Output().c_str()); } } +/* + { + Property p("hello world"); + Property i(100); + Array vals; + vals.push_back(p); + vals.push_back(i); + Property a(vals); + + JsonSerializerVisitor serializer; + serializer.Visit(a); + printf("%s", serializer.Output().c_str()); + input = serializer.Output(); + } +*/ }