1#include <msgpack.hpp>
2#include <gtest/gtest.h>
3#include <cmath>
4
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9enum enum_test {
10    elem
11};
12
13MSGPACK_ADD_ENUM(enum_test);
14
15struct outer_enum {
16    enum enum_test {
17        elem
18    };
19};
20
21MSGPACK_ADD_ENUM(outer_enum::enum_test);
22
23#if !defined(MSGPACK_USE_CPP03)
24
25enum class enum_class_test {
26    elem
27};
28
29MSGPACK_ADD_ENUM(enum_class_test);
30
31struct outer_enum_class {
32    enum class enum_class_test {
33        elem
34    };
35};
36
37MSGPACK_ADD_ENUM(outer_enum_class::enum_class_test);
38
39#endif // !defined(MSGPACK_USE_CPP03)
40
41
42
43using namespace std;
44
45const unsigned int kLoop = 1000;
46const unsigned int kElements = 100;
47const double kEPS = 1e-10;
48
49// bool
50TEST(object_with_zone, bool)
51{
52    bool v = true;
53    msgpack::zone z;
54    msgpack::object obj(v, z);
55    EXPECT_EQ(obj.as<bool>(), v);
56    v = false;
57    EXPECT_TRUE(obj.as<bool>());
58}
59
60// char
61TEST(object_with_zone, char)
62{
63    char v = 1;
64    msgpack::zone z;
65    msgpack::object obj(v, z);
66    EXPECT_EQ(obj.as<char>(), v);
67    v = 2;
68    EXPECT_EQ(obj.as<char>(), 1);
69}
70
71// signed integer family
72TEST(object_with_zone, signed_char)
73{
74    signed char v = -1;
75    msgpack::zone z;
76    msgpack::object obj(v, z);
77    EXPECT_EQ(obj.as<signed char>(), v);
78    v = -2;
79    EXPECT_EQ(obj.as<signed char>(), -1);
80}
81
82TEST(object_with_zone, signed_short)
83{
84    signed short v = -1;
85    msgpack::zone z;
86    msgpack::object obj(v, z);
87    EXPECT_EQ(obj.as<signed short>(), v);
88    v = -2;
89    EXPECT_EQ(obj.as<signed short>(), -1);
90}
91
92TEST(object_with_zone, signed_int)
93{
94    signed int v = -1;
95    msgpack::zone z;
96    msgpack::object obj(v, z);
97    EXPECT_EQ(obj.as<signed int>(), v);
98    v = -2;
99    EXPECT_EQ(obj.as<signed int>(), -1);
100}
101
102TEST(object_with_zone, signed_long)
103{
104    signed long v = -1;
105    msgpack::zone z;
106    msgpack::object obj(v, z);
107    EXPECT_EQ(obj.as<signed long>(), v);
108    v = -2;
109    EXPECT_EQ(obj.as<signed long>(), -1);
110}
111
112TEST(object_with_zone, signed_long_long)
113{
114    signed long long v = -1;
115    msgpack::zone z;
116    msgpack::object obj(v, z);
117    EXPECT_EQ(obj.as<signed long long>(), v);
118    v = -2;
119    EXPECT_EQ(obj.as<signed long long>(), -1);
120}
121
122// unsigned integer family
123TEST(object_with_zone, unsigned_char)
124{
125    unsigned char v = 1;
126    msgpack::zone z;
127    msgpack::object obj(v, z);
128    EXPECT_EQ(obj.as<unsigned char>(), v);
129    v = 2;
130    EXPECT_EQ(obj.as<unsigned char>(), 1);
131}
132
133TEST(object_with_zone, unsigned_short)
134{
135    unsigned short v = 1;
136    msgpack::zone z;
137    msgpack::object obj(v, z);
138    EXPECT_EQ(obj.as<unsigned short>(), v);
139    v = 2;
140    EXPECT_EQ(obj.as<unsigned short>(), 1);
141}
142
143TEST(object_with_zone, unsigned_int)
144{
145    unsigned int v = 1;
146    msgpack::zone z;
147    msgpack::object obj(v, z);
148    EXPECT_EQ(obj.as<unsigned int>(), v);
149    v = 2;
150    EXPECT_EQ(obj.as<unsigned int>(), 1u);
151}
152
153TEST(object_with_zone, unsigned_long)
154{
155    unsigned long v = 1;
156    msgpack::zone z;
157    msgpack::object obj(v, z);
158    EXPECT_EQ(obj.as<unsigned long>(), v);
159    v = 2;
160    EXPECT_EQ(obj.as<unsigned long>(), 1u);
161}
162
163TEST(object_with_zone, unsigned_long_long)
164{
165    unsigned long long v = 1;
166    msgpack::zone z;
167    msgpack::object obj(v, z);
168    EXPECT_EQ(obj.as<unsigned long long>(), v);
169    v = 2;
170    EXPECT_EQ(obj.as<unsigned long long>(), 1u);
171}
172
173// float
174TEST(object_with_zone, float)
175{
176    float v = 1.23f;
177    msgpack::zone z;
178    msgpack::object obj(v, z);
179    EXPECT_TRUE(fabs(obj.as<float>() - v) <= kEPS);
180    v = 4.56f;
181    EXPECT_TRUE(fabs(obj.as<float>() - static_cast<float>(1.23)) <= kEPS);
182}
183
184// double
185TEST(object_with_zone, double)
186{
187    double v = 1.23;
188    msgpack::zone z;
189    msgpack::object obj(v, z);
190    EXPECT_TRUE(fabs(obj.as<double>() - v) <= kEPS);
191    v = 4.56;
192    EXPECT_TRUE(fabs(obj.as<double>() - 1.23) <= kEPS);
193}
194
195// vector
196
197TEST(object_with_zone, vector)
198{
199    for (unsigned int k = 0; k < kLoop; k++) {
200        vector<int> v1;
201        v1.push_back(1);
202        for (unsigned int i = 1; i < kElements; i++)
203            v1.push_back(i);
204        msgpack::zone z;
205        msgpack::object obj(v1, z);
206        EXPECT_TRUE(obj.as<vector<int> >() == v1);
207        v1.front() = 42;
208        EXPECT_EQ(obj.as<vector<int> >().front(), 1);
209    }
210}
211
212// vector_char
213TEST(object_with_zone, vector_char)
214{
215    for (unsigned int k = 0; k < kLoop; k++) {
216        vector<char> v1;
217        v1.push_back(1);
218        for (unsigned int i = 1; i < kElements; i++)
219            v1.push_back(static_cast<char>(i));
220        msgpack::zone z;
221        msgpack::object obj(v1, z);
222        EXPECT_TRUE(obj.as<vector<char> >() == v1);
223        v1.front() = 42;
224        EXPECT_EQ(obj.as<vector<char> >().front(), 1);
225    }
226}
227
228TEST(object_without_zone, vector_char)
229{
230    for (unsigned int k = 0; k < kLoop; k++) {
231        vector<char> v1;
232        v1.push_back(1);
233        for (unsigned int i = 1; i < kElements; i++)
234            v1.push_back(static_cast<char>(i));
235        msgpack::object obj(v1);
236        EXPECT_TRUE(obj.as<vector<char> >() == v1);
237        v1.front() = 42;
238        // obj refer to v1
239        EXPECT_EQ(obj.as<vector<char> >().front(), 42);
240    }
241}
242
243// vector_unsgined_char
244TEST(object_with_zone, vector_unsigned_char)
245{
246    if (!msgpack::is_same<uint8_t, unsigned char>::value) return;
247    for (unsigned int k = 0; k < kLoop; k++) {
248        vector<unsigned char> v1;
249        v1.push_back(1);
250        for (unsigned int i = 1; i < kElements; i++)
251            v1.push_back(static_cast<unsigned char>(i));
252        msgpack::zone z;
253        msgpack::object obj(v1, z);
254        EXPECT_TRUE(obj.as<vector<unsigned char> >() == v1);
255        v1.front() = 42;
256        EXPECT_EQ(obj.as<vector<unsigned char> >().front(), 1);
257    }
258}
259
260TEST(object_without_zone, vector_unsigned_char)
261{
262    if (!msgpack::is_same<uint8_t, unsigned char>::value) return;
263    for (unsigned int k = 0; k < kLoop; k++) {
264        vector<unsigned char> v1;
265        v1.push_back(1);
266        for (unsigned int i = 1; i < kElements; i++)
267            v1.push_back(static_cast<unsigned char>(i));
268        msgpack::object obj(v1);
269        EXPECT_TRUE(obj.as<vector<unsigned char> >() == v1);
270        v1.front() = 42;
271        // obj refer to v1
272        EXPECT_EQ(obj.as<vector<unsigned char> >().front(), 42);
273    }
274}
275
276// list
277TEST(object_with_zone, list)
278{
279    for (unsigned int k = 0; k < kLoop; k++) {
280        list<int> v1;
281        v1.push_back(1);
282        for (unsigned int i = 1; i < kElements; i++)
283            v1.push_back(i);
284        msgpack::zone z;
285        msgpack::object obj(v1, z);
286        EXPECT_TRUE(obj.as<list<int> >() == v1);
287        v1.front() = 42;
288        EXPECT_EQ(obj.as<list<int> >().front(), 1);
289    }
290}
291
292// deque
293TEST(object_with_zone, deque)
294{
295    for (unsigned int k = 0; k < kLoop; k++) {
296        deque<int> v1;
297        v1.push_back(1);
298        for (unsigned int i = 1; i < kElements; i++)
299            v1.push_back(i);
300        msgpack::zone z;
301        msgpack::object obj(v1, z);
302        EXPECT_TRUE(obj.as<deque<int> >() == v1);
303        v1.front() = 42;
304        EXPECT_EQ(obj.as<deque<int> >().front(), 1);
305    }
306}
307
308// string
309TEST(object_with_zone, string)
310{
311    string v = "abc";
312    msgpack::zone z;
313    msgpack::object obj(v, z);
314    EXPECT_EQ(obj.as<string>(), v);
315    v[0] = 'd';
316    EXPECT_EQ(obj.as<string>()[0], 'a');
317}
318
319TEST(object_without_zone, string)
320{
321    string v = "abc";
322    msgpack::zone z;
323    msgpack::object obj(v);
324    EXPECT_EQ(obj.as<string>(), v);
325    v[0] = 'd';
326    EXPECT_EQ(obj.as<string>()[0], 'd');
327}
328
329// char*
330TEST(object_with_zone, char_ptr)
331{
332    char v[] = "abc";
333    msgpack::zone z;
334    msgpack::object obj(v, z);
335    EXPECT_EQ(obj.as<string>(), std::string(v));
336    v[0] = 'd';
337    EXPECT_EQ(obj.as<string>()[0], 'a');
338}
339
340TEST(object_without_zone, char_ptr)
341{
342    char v[] = "abc";
343    msgpack::zone z;
344    msgpack::object obj(v);
345    EXPECT_EQ(obj.as<string>(), std::string(v));
346    v[0] = 'd';
347    EXPECT_EQ(obj.as<string>()[0], 'd');
348}
349
350
351// raw_ref
352TEST(object_with_zone, raw_ref)
353{
354    string s = "abc";
355    msgpack::type::raw_ref v(s.data(), static_cast<uint32_t>(s.size()));
356    msgpack::zone z;
357    msgpack::object obj(v, z);
358    EXPECT_TRUE(obj.as<msgpack::type::raw_ref>() == v);
359    s[0] = 'd';
360    // even if with_zone, not copied due to raw_ref
361    // Basically, the combination raw_ref and object::wit_zone
362    // is meaningless.
363    EXPECT_TRUE(obj.as<msgpack::type::raw_ref>() == v);
364}
365
366TEST(object_without_zone, raw_ref)
367{
368    string s = "abc";
369    msgpack::type::raw_ref v(s.data(), static_cast<uint32_t>(s.size()));
370    msgpack::zone z;
371    msgpack::object obj(v);
372    EXPECT_TRUE(obj.as<msgpack::type::raw_ref>() == v);
373    s[0] = 'd';
374    EXPECT_TRUE(obj.as<msgpack::type::raw_ref>() == v);
375}
376
377// pair
378TEST(object_with_zone, pair)
379{
380    typedef pair<int, string> test_t;
381    test_t v(1, "abc");
382    msgpack::zone z;
383    msgpack::object obj(v, z);
384    EXPECT_TRUE(obj.as<test_t>() == v);
385    v.first = 42;
386    EXPECT_EQ(obj.as<test_t>().first, 1);
387}
388
389// set
390TEST(object_with_zone, set)
391{
392    for (unsigned int k = 0; k < kLoop; k++) {
393        set<int> v1;
394        for (unsigned int i = 0; i < kElements; i++)
395            v1.insert(i);
396        msgpack::zone z;
397        msgpack::object obj(v1, z);
398        EXPECT_TRUE(obj.as<set<int> >() == v1);
399    }
400}
401
402// multiset
403TEST(object_with_zone, multiset)
404{
405    for (unsigned int k = 0; k < kLoop; k++) {
406        multiset<int> v1;
407        for (unsigned int i = 0; i < kElements; i++)
408            v1.insert(i % (kElements / 2));
409        msgpack::zone z;
410        msgpack::object obj(v1, z);
411        EXPECT_TRUE(obj.as<multiset<int> >() == v1);
412    }
413}
414
415// map
416TEST(object_with_zone, map)
417{
418    typedef map<int, int> test_t;
419    for (unsigned int k = 0; k < kLoop; k++) {
420        test_t v1;
421        for (unsigned int i = 0; i < kElements; i++)
422            v1.insert(std::make_pair(i, i*2));
423        msgpack::zone z;
424        msgpack::object obj(v1, z);
425        EXPECT_TRUE(obj.as<test_t >() == v1);
426    }
427}
428
429// multimap
430TEST(object_with_zone, multimap)
431{
432    typedef multimap<int, int> test_t;
433    for (unsigned int k = 0; k < kLoop; k++) {
434        test_t v1;
435        for (unsigned int i = 0; i < kElements; i++)
436            v1.insert(std::make_pair(i % (kElements / 2), i*2));
437        msgpack::zone z;
438        msgpack::object obj(v1, z);
439        EXPECT_TRUE(obj.as<test_t >() == v1);
440    }
441}
442
443// msgpack_tuple
444TEST(object_with_zone, msgpack_tuple)
445{
446    typedef msgpack::type::tuple<int, string, bool> test_t;
447    test_t v(1, "abc", true);
448    msgpack::zone z;
449    msgpack::object obj(v, z);
450    EXPECT_EQ(msgpack::type::get<0>(obj.as<test_t>()), 1);
451    EXPECT_EQ(msgpack::type::get<1>(obj.as<test_t>()), "abc");
452    EXPECT_EQ(msgpack::type::get<2>(obj.as<test_t>()), true);
453    msgpack::type::get<0>(v) = 42;
454    EXPECT_EQ(msgpack::type::get<0>(obj.as<test_t>()), 1);
455}
456
457TEST(object_with_zone, msgpack_tuple_empty)
458{
459    typedef msgpack::type::tuple<> test_t;
460    test_t v;
461    msgpack::zone z;
462    msgpack::object obj(v, z);
463    EXPECT_EQ(obj.via.array.size, 0u);
464}
465
466// TR1
467
468#ifdef MSGPACK_HAS_STD_TR1_UNORDERED_MAP
469#include <tr1/unordered_map>
470#include "msgpack/adaptor/tr1/unordered_map.hpp"
471TEST(object_with_zone, tr1_unordered_map)
472{
473    typedef tr1::unordered_map<int, int> test_t;
474    for (unsigned int k = 0; k < kLoop; k++) {
475        test_t v1;
476        for (unsigned int i = 0; i < kElements; i++)
477            v1[rand()] = rand();
478        msgpack::zone z;
479        msgpack::object obj(v1, z);
480        test_t v2 = obj.as<test_t>();
481        EXPECT_EQ(v1.size(), v2.size());
482        test_t::const_iterator it;
483        for (it = v1.begin(); it != v1.end(); ++it) {
484            EXPECT_TRUE(v2.find(it->first) != v2.end());
485            EXPECT_EQ(it->second, v2.find(it->first)->second);
486        }
487    }
488}
489
490
491TEST(object_with_zone, tr1_unordered_multimap)
492{
493    typedef tr1::unordered_multimap<int, int> test_t;
494    for (unsigned int k = 0; k < kLoop; k++) {
495        test_t v1;
496        for (unsigned int i = 0; i < kElements; i++) {
497            int i1 = rand();
498            v1.insert(make_pair(i1, rand()));
499            v1.insert(make_pair(i1, rand()));
500        }
501        msgpack::zone z;
502        msgpack::object obj(v1, z);
503        test_t v2 = obj.as<test_t>();
504        vector<pair<int, int> > vec1, vec2;
505        tr1::unordered_multimap<int, int>::const_iterator it;
506        for (it = v1.begin(); it != v1.end(); ++it)
507            vec1.push_back(make_pair(it->first, it->second));
508        for (it = v2.begin(); it != v2.end(); ++it)
509            vec2.push_back(make_pair(it->first, it->second));
510        EXPECT_EQ(v1.size(), v2.size());
511        EXPECT_EQ(vec1.size(), vec2.size());
512        sort(vec1.begin(), vec1.end());
513        sort(vec2.begin(), vec2.end());
514        EXPECT_TRUE(vec1 == vec2);
515    }
516}
517#endif
518
519#ifdef MSGPACK_HAS_STD_TR1_UNORDERED_SET
520#include <tr1/unordered_set>
521#include "msgpack/adaptor/tr1/unordered_set.hpp"
522TEST(object_with_zone, tr1_unordered_set)
523{
524    typedef tr1::unordered_set<int> test_t;
525    for (unsigned int k = 0; k < kLoop; k++) {
526        test_t v1;
527        for (unsigned int i = 0; i < kElements; i++)
528            v1.insert(rand());
529        msgpack::zone z;
530        msgpack::object obj(v1, z);
531        test_t v2 = obj.as<test_t>();
532        EXPECT_EQ(v1.size(), v2.size());
533        tr1::unordered_set<int>::const_iterator it;
534        for (it = v1.begin(); it != v1.end(); ++it)
535            EXPECT_TRUE(v2.find(*it) != v2.end());
536    }
537}
538
539TEST(object_with_zone, tr1_unordered_multiset)
540{
541    typedef tr1::unordered_set<int> test_t;
542    for (unsigned int k = 0; k < kLoop; k++) {
543        test_t v1;
544        for (unsigned int i = 0; i < kElements; i++) {
545            int i1 = rand();
546            v1.insert(i1);
547            v1.insert(i1);
548        }
549        msgpack::zone z;
550        msgpack::object obj(v1, z);
551        test_t v2 = obj.as<test_t>();
552        vector<int> vec1, vec2;
553        tr1::unordered_multiset<int>::const_iterator it;
554        for (it = v1.begin(); it != v1.end(); ++it)
555            vec1.push_back(*it);
556        for (it = v2.begin(); it != v2.end(); ++it)
557            vec2.push_back(*it);
558        EXPECT_EQ(v1.size(), v2.size());
559        EXPECT_EQ(vec1.size(), vec2.size());
560        sort(vec1.begin(), vec1.end());
561        sort(vec2.begin(), vec2.end());
562        EXPECT_TRUE(vec1 == vec2);
563    }
564}
565#endif
566
567#ifdef MSGPACK_HAS_STD_UNORDERED_MAP
568#include <unordered_map>
569#include "msgpack/adaptor/tr1/unordered_map.hpp"
570TEST(object_with_zone, unordered_map)
571{
572    typedef unordered_map<int, int> test_t;
573    for (unsigned int k = 0; k < kLoop; k++) {
574        test_t v1;
575        for (unsigned int i = 0; i < kElements; i++)
576            v1[rand()] = rand();
577        msgpack::zone z;
578        msgpack::object obj(v1, z);
579        test_t v2 = obj.as<test_t>();
580        EXPECT_EQ(v1.size(), v2.size());
581        test_t::const_iterator it;
582        for (it = v1.begin(); it != v1.end(); ++it) {
583            EXPECT_TRUE(v2.find(it->first) != v2.end());
584            EXPECT_EQ(it->second, v2.find(it->first)->second);
585        }
586    }
587}
588
589TEST(object_with_zone, unordered_multimap)
590{
591   typedef unordered_multimap<int, int> test_t;
592    for (unsigned int k = 0; k < kLoop; k++) {
593        test_t v1;
594        for (unsigned int i = 0; i < kElements; i++) {
595            int i1 = rand();
596            v1.insert(make_pair(i1, rand()));
597            v1.insert(make_pair(i1, rand()));
598        }
599        msgpack::zone z;
600        msgpack::object obj(v1, z);
601        test_t v2 = obj.as<test_t>();
602        vector<pair<int, int> > vec1, vec2;
603        unordered_multimap<int, int>::const_iterator it;
604        for (it = v1.begin(); it != v1.end(); ++it)
605            vec1.push_back(make_pair(it->first, it->second));
606        for (it = v2.begin(); it != v2.end(); ++it)
607            vec2.push_back(make_pair(it->first, it->second));
608        EXPECT_EQ(v1.size(), v2.size());
609        EXPECT_EQ(vec1.size(), vec2.size());
610        sort(vec1.begin(), vec1.end());
611        sort(vec2.begin(), vec2.end());
612        EXPECT_TRUE(vec1 == vec2);
613    }
614}
615#endif
616
617#ifdef MSGPACK_HAS_STD_UNORDERED_SET
618#include <unordered_set>
619#include "msgpack/adaptor/tr1/unordered_set.hpp"
620TEST(object_with_zone, unordered_set)
621{
622    typedef unordered_set<int> test_t;
623    for (unsigned int k = 0; k < kLoop; k++) {
624        test_t v1;
625        for (unsigned int i = 0; i < kElements; i++)
626            v1.insert(rand());
627        msgpack::zone z;
628        msgpack::object obj(v1, z);
629        test_t v2 = obj.as<test_t>();
630        EXPECT_EQ(v1.size(), v2.size());
631        unordered_set<int>::const_iterator it;
632        for (it = v1.begin(); it != v1.end(); ++it)
633            EXPECT_TRUE(v2.find(*it) != v2.end());
634    }
635}
636
637TEST(object_with_zone, unordered_multiset)
638{
639    typedef unordered_set<int> test_t;
640    for (unsigned int k = 0; k < kLoop; k++) {
641        test_t v1;
642        for (unsigned int i = 0; i < kElements; i++) {
643            int i1 = rand();
644            v1.insert(i1);
645            v1.insert(i1);
646        }
647        msgpack::zone z;
648        msgpack::object obj(v1, z);
649        test_t v2 = obj.as<test_t>();
650        vector<int> vec1, vec2;
651        unordered_multiset<int>::const_iterator it;
652        for (it = v1.begin(); it != v1.end(); ++it)
653            vec1.push_back(*it);
654        for (it = v2.begin(); it != v2.end(); ++it)
655            vec2.push_back(*it);
656        EXPECT_EQ(v1.size(), v2.size());
657        EXPECT_EQ(vec1.size(), vec2.size());
658        sort(vec1.begin(), vec1.end());
659        sort(vec2.begin(), vec2.end());
660        EXPECT_TRUE(vec1 == vec2);
661    }
662}
663#endif
664
665// User defined class
666class TestClass
667{
668public:
669    TestClass() : i(0), s("kzk") {}
670    int i;
671    string s;
672    MSGPACK_DEFINE(i, s);
673};
674
675TEST(object_with_zone, user_defined)
676{
677    TestClass v1;
678    msgpack::zone z;
679    msgpack::object obj(v1, z);
680    TestClass v2 = obj.as<TestClass>();
681    EXPECT_EQ(v1.i, v2.i);
682    EXPECT_EQ(v1.s, v2.s);
683}
684
685TEST(object_with_zone, construct_enum)
686{
687    msgpack::zone z;
688    msgpack::object obj(elem, z);
689    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
690    EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64);
691}
692
693#if !defined(MSGPACK_USE_CPP03)
694
695TEST(object_with_zone, construct_enum_newstyle)
696{
697    msgpack::zone z;
698    msgpack::object obj(enum_test::elem, z);
699    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
700    EXPECT_EQ(elem, obj.via.u64);
701}
702
703#endif // !defined(MSGPACK_USE_CPP03)
704
705TEST(object_with_zone, construct_enum_outer)
706{
707    msgpack::zone z;
708    msgpack::object obj(outer_enum::elem, z);
709    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
710    EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64);
711}
712
713// User defined inheriting classes
714struct top {
715    int t;
716    MSGPACK_DEFINE(t);
717};
718
719struct mid1 : top {
720    int m1;
721    MSGPACK_DEFINE(MSGPACK_BASE(top), m1);
722};
723
724struct mid2 : top {
725    int m2;
726    MSGPACK_DEFINE(m2, MSGPACK_BASE(top));
727};
728
729struct bottom : mid1, mid2 {
730    int b;
731    MSGPACK_DEFINE(MSGPACK_BASE(mid1), MSGPACK_BASE(mid2), b);
732};
733
734TEST(object_with_zone, user_defined_non_virtual)
735{
736    bottom b;
737    b.b = 1;
738    b.m1 = 2;
739    b.m2 = 3;
740    b.mid1::t = 4;
741    b.mid2::t = 5;
742
743    msgpack::zone z;
744    msgpack::object obj(b, z);
745    bottom br = obj.as<bottom>();
746    EXPECT_EQ(b.b, br.b);
747    EXPECT_EQ(b.m1, br.m1);
748    EXPECT_EQ(b.m2, br.m2);
749    EXPECT_EQ(b.mid1::t, br.mid1::t);
750    EXPECT_EQ(b.mid2::t, br.mid2::t);
751}
752
753struct v_top {
754    int t;
755    MSGPACK_DEFINE(t);
756};
757
758struct v_mid1 : virtual v_top {
759    int m1;
760    MSGPACK_DEFINE(m1);
761};
762
763struct v_mid2 : virtual v_top {
764    int m2;
765    MSGPACK_DEFINE(m2);
766};
767
768struct v_bottom : v_mid1, v_mid2 {
769    int b;
770    MSGPACK_DEFINE(MSGPACK_BASE(v_mid1), MSGPACK_BASE(v_mid2), MSGPACK_BASE(v_top), b);
771};
772
773TEST(object_with_zone, user_defined_virtual)
774{
775    v_bottom b;
776    b.b = 1;
777    b.m1 = 2;
778    b.m2 = 3;
779    b.t = 4;
780
781    msgpack::zone z;
782    msgpack::object obj(b, z);
783    v_bottom br = obj.as<v_bottom>();
784    EXPECT_EQ(b.b, br.b);
785    EXPECT_EQ(b.m1, br.m1);
786    EXPECT_EQ(b.m2, br.m2);
787    EXPECT_EQ(b.t, br.t);
788}
789
790#if !defined(MSGPACK_USE_CPP03)
791
792TEST(object_with_zone, construct_enum_outer_newstyle)
793{
794    msgpack::zone z;
795    msgpack::object obj(outer_enum::enum_test::elem, z);
796    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
797    EXPECT_EQ(elem, obj.via.u64);
798}
799
800TEST(object_with_zone, construct_class_enum)
801{
802    msgpack::zone z;
803    msgpack::object obj(enum_class_test::elem, z);
804    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
805    EXPECT_EQ(elem, obj.via.u64);
806}
807
808
809TEST(object_with_zone, construct_class_enum_outer)
810{
811    msgpack::zone z;
812    msgpack::object obj(outer_enum_class::enum_class_test::elem, z);
813    EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type);
814    EXPECT_EQ(elem, obj.via.u64);
815}
816
817
818TEST(object_with_zone, array)
819{
820    typedef array<int, kElements> test_t;
821    for (unsigned int k = 0; k < kLoop; k++) {
822        test_t v1;
823        v1[0] = 1;
824        for (unsigned int i = 1; i < kElements; i++)
825            v1[i] = rand();
826        msgpack::zone z;
827        msgpack::object obj(v1, z);
828        EXPECT_TRUE(obj.as<test_t>() == v1);
829        v1.front() = 42;
830        EXPECT_EQ(obj.as<test_t>().front(), 1);
831    }
832}
833
834TEST(object_with_zone, array_char)
835{
836    typedef array<char, kElements> test_t;
837    for (unsigned int k = 0; k < kLoop; k++) {
838        test_t v1;
839        v1[0] = 1;
840        for (unsigned int i = 1; i < kElements; i++)
841            v1[i] = rand();
842        msgpack::zone z;
843        msgpack::object obj(v1, z);
844        EXPECT_TRUE(obj.as<test_t>() == v1);
845        v1.front() = 42;
846        EXPECT_EQ(obj.as<test_t>().front(), 1);
847    }
848}
849
850TEST(object_without_zone, array_char)
851{
852    typedef array<char, kElements> test_t;
853    for (unsigned int k = 0; k < kLoop; k++) {
854        test_t v1;
855        v1[0] = 1;
856        for (unsigned int i = 1; i < kElements; i++)
857            v1[i] = rand();
858        msgpack::object obj(v1);
859        EXPECT_TRUE(obj.as<test_t>() == v1);
860        v1.front() = 42;
861        // obj refer to v1
862        EXPECT_EQ(obj.as<test_t>().front(), 42);
863    }
864}
865
866TEST(object_with_zone, array_unsigned_char)
867{
868    if (!msgpack::is_same<uint8_t, unsigned char>::value) return;
869    typedef array<unsigned char, kElements> test_t;
870    for (unsigned int k = 0; k < kLoop; k++) {
871        test_t v1;
872        v1[0] = 1;
873        for (unsigned int i = 1; i < kElements; i++)
874            v1[i] = rand();
875        msgpack::zone z;
876        msgpack::object obj(v1, z);
877        EXPECT_TRUE(obj.as<test_t>() == v1);
878        v1.front() = 42;
879        EXPECT_EQ(obj.as<test_t>().front(), 1);
880    }
881}
882
883TEST(object_without_zone, array_unsigned_char)
884{
885    if (!msgpack::is_same<uint8_t, unsigned char>::value) return;
886    typedef array<unsigned char, kElements> test_t;
887    for (unsigned int k = 0; k < kLoop; k++) {
888        test_t v1;
889        v1[0] = 1;
890        for (unsigned int i = 1; i < kElements; i++)
891            v1[i] = rand();
892        msgpack::object obj(v1);
893        EXPECT_TRUE(obj.as<test_t>() == v1);
894        v1.front() = 42;
895        // obj refer to v1
896        EXPECT_EQ(obj.as<test_t>().front(), 42);
897    }
898}
899
900
901TEST(object_with_zone, forward_list)
902{
903    for (unsigned int k = 0; k < kLoop; k++) {
904        forward_list<int> v1;
905        for (unsigned int i = 0; i < kElements; i++)
906            v1.push_front(i);
907        msgpack::zone z;
908        msgpack::object obj(v1, z);
909        EXPECT_TRUE(obj.as<forward_list<int> >() == v1);
910        v1.front() = 42;
911        EXPECT_EQ(obj.as<forward_list<int> >().front(), static_cast<int>(kElements - 1));
912    }
913}
914
915TEST(object_with_zone, tuple)
916{
917    typedef tuple<int, string, bool> test_t;
918    test_t v(1, "abc", true);
919    msgpack::zone z;
920    msgpack::object obj(v, z);
921    EXPECT_TRUE(obj.as<test_t>() == v);
922}
923
924TEST(object_with_zone, tuple_empty)
925{
926    typedef tuple<> test_t;
927    test_t v;
928    msgpack::zone z;
929    msgpack::object obj(v, z);
930    EXPECT_TRUE(obj.as<test_t>() == v);
931}
932
933#endif // !defined(MSGPACK_USE_CPP03)
934
935TEST(object_with_zone, ext_empty)
936{
937    msgpack::type::ext v;
938    msgpack::zone z;
939    msgpack::object obj(v, z);
940    EXPECT_TRUE(obj.as<msgpack::type::ext>() == v);
941    EXPECT_TRUE(obj.as<msgpack::type::ext_ref>() == v);
942}
943
944TEST(object_with_zone, ext)
945{
946    msgpack::type::ext v(42, 10);
947    for (int i = 0; i < 10; ++i) v.data()[i] = i;
948    msgpack::zone z;
949    msgpack::object obj(v, z);
950    EXPECT_TRUE(obj.as<msgpack::type::ext>() == v);
951    EXPECT_TRUE(obj.as<msgpack::type::ext_ref>() == v);
952}
953
954TEST(object_with_zone, ext_from_buf)
955{
956    char const buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
957    msgpack::type::ext v(42, buf, sizeof(buf));
958    msgpack::zone z;
959    msgpack::object obj(v, z);
960    EXPECT_TRUE(obj.as<msgpack::type::ext>() == v);
961    EXPECT_TRUE(obj.as<msgpack::type::ext_ref>() == v);
962}
963
964TEST(object_with_zone, ext_ref_empty)
965{
966    msgpack::type::ext_ref v;
967    msgpack::zone z;
968    msgpack::object obj(v, z);
969    EXPECT_TRUE(obj.as<msgpack::type::ext>() == v);
970    EXPECT_TRUE(obj.as<msgpack::type::ext_ref>() == v);
971}
972
973TEST(object_with_zone, ext_ref_from_buf)
974{
975    char const buf[] = { 77, 1, 2, 3, 4, 5, 6, 7, 8, 9};
976    msgpack::type::ext_ref v(buf, sizeof(buf));
977    msgpack::zone z;
978    msgpack::object obj(v, z);
979    EXPECT_TRUE(obj.as<msgpack::type::ext>() == v);
980    EXPECT_TRUE(obj.as<msgpack::type::ext_ref>() == v);
981}
982