Loki-Astari / ThorsMongo

C++ MongoDB API and BSON/JSON Serialization library
GNU General Public License v3.0
316 stars 72 forks source link

Is vector supported as a member within a class? #14

Closed byzhang closed 9 years ago

byzhang commented 9 years ago

Like

class MyClass
    {   
        int         data1;
        float       data2;
        std::string data3;
        std::vector<int> data4;
  }

I tried it in SerializeTest.cpp, but it seems not working?

Loki-Astari commented 9 years ago

Yes that should work as expected. You will need to include the "SerUtil.h" as this includes the definitions for all the standard types.

 #include "ThorSerialize/SerUtil.h"

See example 2: https://github.com/Loki-Astari/ThorsSerializer/blob/master/doc/example2.md

Here is a test I wrote:

#include <string>
#include "ThorSerialize/Traits.h"
#include "ThorSerialize/SerUtil.h"
#include "ThorSerialize/JsonThor.h"

/* A class that you want to serialize. */
class MyClass
{
    int         data1;
    float       data2;
    std::string data3;
    std::vector<int> data4;
    public:
        MyClass(int data1, float data2, std::string const& data3, std::vector<int> const& data4)
            : data1(data1)
            , data2(data2)
            , data3(data3)
            , data4(data4)
        {}

    // This is only required if the members are private.
    friend struct ThorsAnvil::Serialize::Traits<MyClass>;
};

/*
 * Though there is no code involved, you do need to set up
 * this structure to tell the library what fields need to be serialized.
 * To do this use the macro:  ThorsAnvil_MakeTrait()
 * Specifying your class, and a list of members to serialize.
 */
ThorsAnvil_MakeTrait(MyClass, data1, data2, data3, data4);

int main()
{
    MyClass   x { 10, 12.3, "Help", {1,2,3,4}};

    namespace TS = ThorsAnvil::Serialize;
    std::cout << TS::jsonExport(x);
}

g++ -std=c++14 test.cpp -lThorSerialize14 ./a.out { "data1": 10, "data2": 12.3, "data3": "Help", "data4": [ 1, 2, 3, 4] }

byzhang commented 9 years ago

Yes, your example does work.

Here is my change:

diff --git i/src/Serialize/test/SerializeTest.cpp w/src/Serialize/test/SerializeTest.cpp
index 1f304f1..51d2bec 100644
--- i/src/Serialize/test/SerializeTest.cpp
+++ w/src/Serialize/test/SerializeTest.cpp
@@ -9,10 +9,10 @@
 #include <algorithm>

-std::string const testData1 = R"({"theInteger":34,"aNonRealValue":56.78,"test":true,"normalString":"Done"})";
-std::string const testData2 = R"({"theInteger":456,"aNonRealValue":89.101,"test":false,"normalString":"Akinkthatisnotstraight","data1":1,"data2":2})";
-std::string const testData3 = R"({"member1":{"theInteger":234567,"aNonRealValue":123.45,"test":true,"normalString":"NotASquareAndOnlyOneSide"})"
-                              R"(,"member2":{"theInteger":234567,"aNonRealValue":123.45,"test":true,"normalString":"NotASquareAndOnlyOneSide","data1":67,"data2":11}})";
+std::string const testData1 = R"({"theInteger":34,"aNonRealValue":56.78,"test":true,"normalString":"Done","numberArrays":[0,1,2]})";
+std::string const testData2 = R"({"theInteger":456,"aNonRealValue":89.101,"test":false,"normalString":"Akinkthatisnotstraight","numberArrays":[0,1,2],"data1":1,"data2":2})";
+std::string const testData3 = R"({"member1":{"theInteger":234567,"aNonRealValue":123.45,"test":true,"normalString":"NotASquareAndOnlyOneSide","numberArrays":[0,1,2]})"
+                              R"(,"member2":{"theInteger":234567,"aNonRealValue":123.45,"test":true,"normalString":"NotASquareAndOnlyOneSide","numberArrays":[0,1,2],"data1":67,"data2":11}})";

 TEST(SerializeTest, SerializeStructureOfValue)
 {
diff --git i/src/Serialize/test/SerializeTest.h w/src/Serialize/test/SerializeTest.h
index 0c969ba..925b6c9 100644
--- i/src/Serialize/test/SerializeTest.h
+++ w/src/Serialize/test/SerializeTest.h
@@ -3,6 +3,7 @@
 #define THORS_ANVIL_SERIALIZE_TEST_SERIALIZE_TEST_EXTRA_H

 #include "../Traits.h"
+#include "ThorSerialize/SerUtil.h"

 enum RGB { Red, Green, Blue };
 struct EumHolder
@@ -17,6 +18,7 @@ class SerializeTestExtra
     double      aNonRealValue;
     bool        test;
     std::string normalString;
+    std::vector<int> numberArrays;

     friend class ThorsAnvil::Serialize::Traits<SerializeTestExtra>;
     public:
@@ -27,6 +29,7 @@ class SerializeTestExtra
             , aNonRealValue(aNonRealValue)
             , test(test)
             , normalString(normalString)
+            , numberArrays({0, 1, 2})
         {}
         ~SerializeTestExtra()
         {}
@@ -69,7 +72,7 @@ class SerializeTestMembers

 ThorsAnvil_MakeEnum(RGB, Red, Green, Blue);
 ThorsAnvil_MakeTrait(EumHolder, value);
-ThorsAnvil_MakeTrait(SerializeTestExtra, theInteger, aNonRealValue, test, normalString);
+ThorsAnvil_MakeTrait(SerializeTestExtra, theInteger, aNonRealValue, test, normalString, numberArrays);
 ThorsAnvil_ExpandTrait(SerializeTestExtra, SerializeTestChild, data1, data2);
 ThorsAnvil_MakeTrait(SerializeTestMembers, member1, member2);

And the error is:

SerializeTest.cpp:29: Failure
Value of: result
  Actual: "{\"theInteger\":34,\"aNonRealValue\":56.78,\"test\":true,\"normalString\":\"Done\"}"
Expected: testData1
Which is: "{\"theInteger\":34,\"aNonRealValue\":56.78,\"test\":true,\"normalString\":\"Done\",\"numberArrays\":[0,1,2]}"
[  FAILED  ] SerializeTest.SerializeStructureOfValue (0 ms)

I cannot spot where goes wrong.

Loki-Astari commented 9 years ago

Try doing a make veryclean followed by a make test. It looks like a bug in the makefile that is not detecting changes and thus non re-building all the files.

byzhang commented 9 years ago

You are right. Even make clean is not enough.