• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 
11 // Intentionally no include guards (to be included more than once)
12 
13 #if !defined(CHTYPE) || !defined(T) || !defined(PTREE) || !defined(NOCASE) || !defined(WIDECHAR)
14 #   error No character type specified
15 #endif
16 
test_debug(PTREE *)17 void test_debug(PTREE *)
18 {
19 #if 0
20     // Check count
21     BOOST_TEST(PTREE::debug_get_instances_count() == 0);
22 
23     {
24 
25         // Create ptrees
26         PTREE pt1, pt2;
27         BOOST_TEST(PTREE::debug_get_instances_count() == 2);
28 
29         // Create PTREE
30         PTREE *pt3 = new PTREE;
31         BOOST_TEST(PTREE::debug_get_instances_count() == 3);
32 
33         // Insert
34         pt1.push_back(std::make_pair(T("key"), *pt3));
35         BOOST_TEST(PTREE::debug_get_instances_count() == 4);
36 
37         // Insert
38         pt2.push_back(std::make_pair(T("key"), *pt3));
39         BOOST_TEST(PTREE::debug_get_instances_count() == 5);
40 
41         // Clear
42         pt1.clear();
43         BOOST_TEST(PTREE::debug_get_instances_count() == 4);
44 
45         // Clear
46         pt2.clear();
47         BOOST_TEST(PTREE::debug_get_instances_count() == 3);
48 
49         // Delete
50         delete pt3;
51         BOOST_TEST(PTREE::debug_get_instances_count() == 2);
52 
53     }
54 
55     // Check count
56     BOOST_TEST(PTREE::debug_get_instances_count() == 0);
57 #endif
58 }
59 
test_constructor_destructor_assignment(PTREE *)60 void test_constructor_destructor_assignment(PTREE *)
61 {
62 
63     {
64 
65         // Test constructor from string
66         PTREE pt1(T("data"));
67         BOOST_TEST(pt1.data() == T("data"));
68         //BOOST_TEST(PTREE::debug_get_instances_count() == 1);
69 
70         // Do insertions
71         PTREE &tmp1 = pt1.put(T("key1"), T("data1"));
72         PTREE &tmp2 = pt1.put(T("key2"), T("data2"));
73         tmp1.put(T("key3"), T("data3"));
74         tmp2.put(T("key4"), T("data4"));
75         //BOOST_TEST(PTREE::debug_get_instances_count() == 5);
76 
77         // Make a copy using copy constructor
78         PTREE *pt2 = new PTREE(pt1);
79         BOOST_TEST(*pt2 == pt1);
80         //BOOST_TEST(PTREE::debug_get_instances_count() == 10);
81 
82         // Make a copy using = operator
83         PTREE *pt3 = new PTREE;
84         *pt3 = *pt2;
85         BOOST_TEST(*pt3 == *pt2);
86         //BOOST_TEST(PTREE::debug_get_instances_count() == 15);
87 
88         // Test self assignment
89         pt1 = pt1;
90         BOOST_TEST(pt1 == *pt2);
91         BOOST_TEST(pt1 == *pt3);
92         //BOOST_TEST(PTREE::debug_get_instances_count() == 15);
93 
94         // Destroy
95         delete pt2;
96         //BOOST_TEST(PTREE::debug_get_instances_count() == 10);
97 
98         // Destroy
99         delete pt3;
100         //BOOST_TEST(PTREE::debug_get_instances_count() == 5);
101 
102     }
103 
104     // Check count
105     //BOOST_TEST(PTREE::debug_get_instances_count() == 0);
106 
107 }
108 
test_insertion(PTREE *)109 void test_insertion(PTREE *)
110 {
111 
112     // Do insertions
113     PTREE pt;
114     PTREE tmp1(T("data1"));
115     PTREE tmp2(T("data2"));
116     PTREE tmp3(T("data3"));
117     PTREE tmp4(T("data4"));
118     PTREE::iterator it1 = pt.insert(pt.end(), std::make_pair(T("key1"), tmp1));
119     PTREE::iterator it2 = pt.insert(it1, std::make_pair(T("key2"), tmp2));
120     PTREE::iterator it3 = it1->second.push_back(std::make_pair(T("key3"), tmp3));
121     PTREE::iterator it4 = it1->second.push_front(std::make_pair(T("key4"), tmp4));
122     it2->second.insert(it2->second.end(), it1->second.begin(), it1->second.end());
123 
124     // Check instance count
125     //BOOST_TEST(PTREE::debug_get_instances_count() == 11);
126 
127     // Check contents
128     BOOST_TEST(pt.get(T("key1"), T("")) == T("data1"));
129     BOOST_TEST(pt.get(T("key2"), T("")) == T("data2"));
130     BOOST_TEST(pt.get(T("key1.key3"), T("")) == T("data3"));
131     BOOST_TEST(pt.get(T("key1.key4"), T("")) == T("data4"));
132     BOOST_TEST(pt.get(T("key2.key3"), T("")) == T("data3"));
133     BOOST_TEST(pt.get(T("key2.key4"), T("")) == T("data4"));
134 
135     // Check sequence
136     PTREE::iterator it = it2;
137     ++it; BOOST_TEST(it == it1);
138     ++it; BOOST_TEST(it == pt.end());
139     it = it4;
140     ++it; BOOST_TEST(it == it3);
141     ++it; BOOST_TEST(it == it1->second.end());
142 
143 }
144 
test_erasing(PTREE *)145 void test_erasing(PTREE *)
146 {
147 
148     // Do insertions
149     PTREE pt;
150     PTREE tmp1(T("data1"));
151     PTREE tmp2(T("data2"));
152     PTREE tmp3(T("data3"));
153     PTREE tmp4(T("data4"));
154     PTREE::iterator it1 = pt.insert(pt.end(), std::make_pair(T("key1"), tmp1));
155     PTREE::iterator it2 = pt.insert(it1, std::make_pair(T("key2"), tmp2));
156     it1->second.push_back(std::make_pair(T("key"), tmp3));
157     it1->second.push_front(std::make_pair(T("key"), tmp4));
158     it2->second.insert(it2->second.end(), it1->second.begin(), it1->second.end());
159 
160     // Check instance count
161     //BOOST_TEST(PTREE::debug_get_instances_count() == 11);
162 
163     // Test range erase
164     PTREE::iterator it = it1->second.erase(it1->second.begin(), it1->second.end());
165     BOOST_TEST(it == it1->second.end());
166     //BOOST_TEST(PTREE::debug_get_instances_count() == 9);
167 
168     // Test single erase
169     PTREE::size_type n = pt.erase(T("key1"));
170     BOOST_TEST(n == 1);
171     //BOOST_TEST(PTREE::debug_get_instances_count() == 8);
172 
173     // Test multiple erase
174     n = it2->second.erase(T("key"));
175     BOOST_TEST(n == 2);
176     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
177 
178     // Test one more erase
179     n = pt.erase(T("key2"));
180     BOOST_TEST(n == 1);
181     //BOOST_TEST(PTREE::debug_get_instances_count() == 5);
182 
183 }
184 
test_clear(PTREE *)185 void test_clear(PTREE *)
186 {
187 
188     // Do insertions
189     PTREE pt(T("data"));
190     pt.push_back(std::make_pair(T("key"), PTREE(T("data"))));
191 
192     // Check instance count
193     //BOOST_TEST(PTREE::debug_get_instances_count() == 2);
194 
195     // Test clear
196     pt.clear();
197     BOOST_TEST(pt.empty());
198     BOOST_TEST(pt.data().empty());
199     //BOOST_TEST(PTREE::debug_get_instances_count() == 1);
200 
201 }
202 
test_pushpop(PTREE *)203 void test_pushpop(PTREE *)
204 {
205 
206     // Do insertions
207     PTREE pt;
208     PTREE tmp1(T("data1"));
209     PTREE tmp2(T("data2"));
210     PTREE tmp3(T("data3"));
211     PTREE tmp4(T("data4"));
212     pt.push_back(std::make_pair(T("key3"), tmp3));
213     pt.push_front(std::make_pair(T("key2"), tmp2));
214     pt.push_back(std::make_pair(T("key4"), tmp4));
215     pt.push_front(std::make_pair(T("key1"), tmp1));
216 
217     // Check instance count
218     //BOOST_TEST(PTREE::debug_get_instances_count() == 9);
219 
220     // Check sequence
221     PTREE::iterator it = pt.begin();
222     BOOST_TEST(it->first == T("key1")); ++it;
223     BOOST_TEST(it->first == T("key2")); ++it;
224     BOOST_TEST(it->first == T("key3")); ++it;
225     BOOST_TEST(it->first == T("key4")); ++it;
226     BOOST_TEST(it == pt.end());
227 
228     // Test pops
229     pt.pop_back();
230     //BOOST_TEST(PTREE::debug_get_instances_count() == 8);
231     BOOST_TEST(pt.front().second.data() == T("data1"));
232     BOOST_TEST(pt.back().second.data() == T("data3"));
233     pt.pop_front();
234     //BOOST_TEST(PTREE::debug_get_instances_count() == 7);
235     BOOST_TEST(pt.front().second.data() == T("data2"));
236     BOOST_TEST(pt.back().second.data() == T("data3"));
237     pt.pop_back();
238     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
239     BOOST_TEST(pt.front().second.data() == T("data2"));
240     BOOST_TEST(pt.back().second.data() == T("data2"));
241     pt.pop_front();
242     //BOOST_TEST(PTREE::debug_get_instances_count() == 5);
243     BOOST_TEST(pt.empty());
244 
245 }
246 
test_container_iteration(PTREE *)247 void test_container_iteration(PTREE *)
248 {
249 
250     // Do insertions
251     PTREE pt;
252     pt.put(T("key3"), T(""));
253     pt.put(T("key1"), T(""));
254     pt.put(T("key4"), T(""));
255     pt.put(T("key2"), T(""));
256 
257     // iterator
258     {
259         PTREE::iterator it = pt.begin();
260         BOOST_TEST(it->first == T("key3")); ++it;
261         BOOST_TEST(it->first == T("key1")); ++it;
262         BOOST_TEST(it->first == T("key4")); ++it;
263         BOOST_TEST(it->first == T("key2")); ++it;
264         BOOST_TEST(it == pt.end());
265     }
266 
267     // const_iterator
268     {
269         PTREE::const_iterator it = pt.begin();
270         BOOST_TEST(it->first == T("key3")); ++it;
271         BOOST_TEST(it->first == T("key1")); ++it;
272         BOOST_TEST(it->first == T("key4")); ++it;
273         BOOST_TEST(it->first == T("key2")); ++it;
274         BOOST_TEST(it == pt.end());
275     }
276 
277     // reverse_iterator
278     {
279         PTREE::reverse_iterator it = pt.rbegin();
280         BOOST_TEST(it->first == T("key2")); ++it;
281         BOOST_TEST(it->first == T("key4")); ++it;
282         BOOST_TEST(it->first == T("key1")); ++it;
283         BOOST_TEST(it->first == T("key3")); ++it;
284         BOOST_TEST(it == pt.rend());
285     }
286 
287     // const_reverse_iterator
288     {
289         PTREE::const_reverse_iterator it = pt.rbegin();
290         BOOST_TEST(it->first == T("key2")); ++it;
291         BOOST_TEST(it->first == T("key4")); ++it;
292         BOOST_TEST(it->first == T("key1")); ++it;
293         BOOST_TEST(it->first == T("key3")); ++it;
294         BOOST_TEST(it == PTREE::const_reverse_iterator(pt.rend()));
295     }
296 
297 }
298 
test_swap(PTREE *)299 void test_swap(PTREE *)
300 {
301 
302     PTREE pt1, pt2;
303 
304     // Do insertions
305     pt1.put(T("key1"), T(""));
306     pt1.put(T("key2"), T(""));
307     pt1.put(T("key1.key3"), T(""));
308     pt1.put(T("key1.key4"), T(""));
309 
310     // Check counts
311     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
312     BOOST_TEST(pt1.size() == 2);
313     BOOST_TEST(pt1.get_child(T("key1")).size() == 2);
314     BOOST_TEST(pt2.size() == 0);
315 
316     // Swap using member function
317     pt1.swap(pt2);
318 
319     // Check counts
320     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
321     BOOST_TEST(pt2.size() == 2);
322     BOOST_TEST(pt2.get_child(T("key1")).size() == 2);
323     BOOST_TEST(pt1.size() == 0);
324 
325     // Swap using free function
326     swap(pt1, pt2);
327 
328     // Check counts
329     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
330     BOOST_TEST(pt1.size() == 2);
331     BOOST_TEST(pt1.get_child(T("key1")).size() == 2);
332     BOOST_TEST(pt2.size() == 0);
333 
334     // Swap using std algorithm
335     std::swap(pt1, pt2);
336 
337     // Check counts
338     //BOOST_TEST(PTREE::debug_get_instances_count() == 6);
339     BOOST_TEST(pt2.size() == 2);
340     BOOST_TEST(pt2.get_child(T("key1")).size() == 2);
341     BOOST_TEST(pt1.size() == 0);
342 
343 }
344 
test_sort_reverse(PTREE *)345 void test_sort_reverse(PTREE *)
346 {
347 
348     PTREE pt;
349 
350     // Do insertions
351     pt.put(T("key2"), T("data2"));
352     pt.put(T("key1"), T("data1"));
353     pt.put(T("key4"), T("data4"));
354     pt.put(T("key3"), T("data3"));
355     pt.put(T("key3.key1"), T(""));
356     pt.put(T("key4.key2"), T(""));
357 
358     // Reverse
359     pt.reverse();
360 
361     // Check sequence
362     {
363         PTREE::iterator it = pt.begin();
364         BOOST_TEST(it->first == T("key3")); ++it;
365         BOOST_TEST(it->first == T("key4")); ++it;
366         BOOST_TEST(it->first == T("key1")); ++it;
367         BOOST_TEST(it->first == T("key2")); ++it;
368         BOOST_TEST(it == pt.end());
369     }
370     // Check sequence using find to check if index is ok
371     {
372         PTREE::iterator it = pt.begin();
373         BOOST_TEST(it == pt.to_iterator(pt.find(T("key3")))); ++it;
374         BOOST_TEST(it == pt.to_iterator(pt.find(T("key4")))); ++it;
375         BOOST_TEST(it == pt.to_iterator(pt.find(T("key1")))); ++it;
376         BOOST_TEST(it == pt.to_iterator(pt.find(T("key2")))); ++it;
377         BOOST_TEST(it == pt.end());
378     }
379 
380     // Sort
381     pt.sort(SortPred<PTREE>());
382 
383     // Check sequence
384     {
385         PTREE::iterator it = pt.begin();
386         BOOST_TEST(it->first == T("key1")); ++it;
387         BOOST_TEST(it->first == T("key2")); ++it;
388         BOOST_TEST(it->first == T("key3")); ++it;
389         BOOST_TEST(it->first == T("key4")); ++it;
390         BOOST_TEST(it == pt.end());
391     }
392     // Check sequence (using find to check if index is ok)
393     {
394         PTREE::iterator it = pt.begin();
395         BOOST_TEST(it == pt.to_iterator(pt.find(T("key1")))); ++it;
396         BOOST_TEST(it == pt.to_iterator(pt.find(T("key2")))); ++it;
397         BOOST_TEST(it == pt.to_iterator(pt.find(T("key3")))); ++it;
398         BOOST_TEST(it == pt.to_iterator(pt.find(T("key4")))); ++it;
399         BOOST_TEST(it == pt.end());
400     }
401 
402     // Sort reverse
403     pt.sort(SortPredRev<PTREE>());
404 
405     // Check sequence
406     {
407         PTREE::iterator it = pt.begin();
408         BOOST_TEST(it->first == T("key4")); ++it;
409         BOOST_TEST(it->first == T("key3")); ++it;
410         BOOST_TEST(it->first == T("key2")); ++it;
411         BOOST_TEST(it->first == T("key1")); ++it;
412         BOOST_TEST(it == pt.end());
413     }
414     // Check sequence (using find to check if index is ok)
415     {
416         PTREE::iterator it = pt.begin();
417         BOOST_TEST(it == pt.to_iterator(pt.find(T("key4")))); ++it;
418         BOOST_TEST(it == pt.to_iterator(pt.find(T("key3")))); ++it;
419         BOOST_TEST(it == pt.to_iterator(pt.find(T("key2")))); ++it;
420         BOOST_TEST(it == pt.to_iterator(pt.find(T("key1")))); ++it;
421         BOOST_TEST(it == pt.end());
422     }
423 
424 }
425 
test_case(PTREE *)426 void test_case(PTREE *)
427 {
428 
429     // Do insertions
430     PTREE pt;
431     pt.put(T("key1"), T("data1"));
432     pt.put(T("KEY2"), T("data2"));
433     pt.put(T("kEy1.keY3"), T("data3"));
434     pt.put(T("KEY1.key4"), T("data4"));
435 
436     // Check findings depending on traits type
437 #if (NOCASE == 0)
438     //BOOST_TEST(PTREE::debug_get_instances_count() == 7);
439     BOOST_TEST(pt.get(T("key1"), T("")) == T("data1"));
440     BOOST_TEST(pt.get(T("key2"), T("")) == T(""));
441     BOOST_TEST(pt.get(T("key1.key3"), T("")) == T(""));
442     BOOST_TEST(pt.get(T("KEY1.key4"), T("")) == T("data4"));
443 #else
444     //BOOST_TEST(PTREE::debug_get_instances_count() == 5);
445     BOOST_TEST(pt.get(T("key1"), T("1")) == pt.get(T("KEY1"), T("2")));
446     BOOST_TEST(pt.get(T("key2"), T("1")) == pt.get(T("KEY2"), T("2")));
447     BOOST_TEST(pt.get(T("key1.key3"), T("1")) == pt.get(T("KEY1.KEY3"), T("2")));
448     BOOST_TEST(pt.get(T("key1.key4"), T("1")) == pt.get(T("KEY1.KEY4"), T("2")));
449 #endif
450 
451     // Do more insertions
452     pt.push_back(PTREE::value_type(T("key1"), PTREE()));
453     pt.push_back(PTREE::value_type(T("key1"), PTREE()));
454 
455     // Test counts
456 #if (NOCASE == 0)
457     BOOST_TEST(pt.count(T("key1")) == 3);
458     BOOST_TEST(pt.count(T("KEY1")) == 1);
459     BOOST_TEST(pt.count(T("key2")) == 0);
460     BOOST_TEST(pt.count(T("KEY2")) == 1);
461     BOOST_TEST(pt.count(T("key3")) == 0);
462     BOOST_TEST(pt.count(T("KEY3")) == 0);
463 #else
464     BOOST_TEST(pt.count(T("key1")) == 3);
465     BOOST_TEST(pt.count(T("KEY1")) == 3);
466     BOOST_TEST(pt.count(T("key2")) == 1);
467     BOOST_TEST(pt.count(T("KEY2")) == 1);
468     BOOST_TEST(pt.count(T("key3")) == 0);
469     BOOST_TEST(pt.count(T("KEY3")) == 0);
470 #endif
471 
472 }
473 
test_comparison(PTREE *)474 void test_comparison(PTREE *)
475 {
476 
477     // Prepare original
478     PTREE pt_orig(T("data"));
479     pt_orig.put(T("key1"), T("data1"));
480     pt_orig.put(T("key1.key3"), T("data2"));
481     pt_orig.put(T("key1.key4"), T("data3"));
482     pt_orig.put(T("key2"), T("data4"));
483 
484     // Test originals
485     {
486         PTREE pt1(pt_orig);
487         PTREE pt2(pt_orig);
488         BOOST_TEST(pt1 == pt2);
489         BOOST_TEST(pt2 == pt1);
490         BOOST_TEST(!(pt1 != pt2));
491         BOOST_TEST(!(pt2 != pt1));
492     }
493 
494     // Test originals with modified case
495 #if (NOCASE != 0)
496     {
497         PTREE pt1(pt_orig);
498         PTREE pt2(pt_orig);
499         pt1.pop_back();
500         pt1.put(T("KEY2"), T("data4"));
501         BOOST_TEST(pt1 == pt2);
502         BOOST_TEST(pt2 == pt1);
503         BOOST_TEST(!(pt1 != pt2));
504         BOOST_TEST(!(pt2 != pt1));
505     }
506 #endif
507 
508     // Test modified copies (both modified the same way)
509     {
510         PTREE pt1(pt_orig);
511         PTREE pt2(pt_orig);
512         pt1.put(T("key1.key5"), T("."));
513         pt2.put(T("key1.key5"), T("."));
514         BOOST_TEST(pt1 == pt2);
515         BOOST_TEST(pt2 == pt1);
516         BOOST_TEST(!(pt1 != pt2));
517         BOOST_TEST(!(pt2 != pt1));
518     }
519 
520     // Test modified copies (modified root data)
521     {
522         PTREE pt1(pt_orig);
523         PTREE pt2(pt_orig);
524         pt1.data() = T("a");
525         pt2.data() = T("b");
526         BOOST_TEST(!(pt1 == pt2));
527         BOOST_TEST(!(pt2 == pt1));
528         BOOST_TEST(pt1 != pt2);
529         BOOST_TEST(pt2 != pt1);
530     }
531 
532     // Test modified copies (added subkeys with different data)
533     {
534         PTREE pt1(pt_orig);
535         PTREE pt2(pt_orig);
536         pt1.put(T("key1.key5"), T("a"));
537         pt2.put(T("key1.key5"), T("b"));
538         BOOST_TEST(!(pt1 == pt2));
539         BOOST_TEST(!(pt2 == pt1));
540         BOOST_TEST(pt1 != pt2);
541         BOOST_TEST(pt2 != pt1);
542     }
543 
544     // Test modified copies (added subkeys with different keys)
545     {
546         PTREE pt1(pt_orig);
547         PTREE pt2(pt_orig);
548         pt1.put(T("key1.key5"), T(""));
549         pt2.put(T("key1.key6"), T(""));
550         BOOST_TEST(!(pt1 == pt2));
551         BOOST_TEST(!(pt2 == pt1));
552         BOOST_TEST(pt1 != pt2);
553         BOOST_TEST(pt2 != pt1);
554     }
555 
556     // Test modified copies (added subkey to only one copy)
557     {
558         PTREE pt1(pt_orig);
559         PTREE pt2(pt_orig);
560         pt1.put(T("key1.key5"), T(""));
561         BOOST_TEST(!(pt1 == pt2));
562         BOOST_TEST(!(pt2 == pt1));
563         BOOST_TEST(pt1 != pt2);
564         BOOST_TEST(pt2 != pt1);
565     }
566 
567 }
568 
test_front_back(PTREE *)569 void test_front_back(PTREE *)
570 {
571 
572     // Do insertions
573     PTREE pt;
574     pt.put(T("key1"), T(""));
575     pt.put(T("key2"), T(""));
576 
577     // Check front and back
578     BOOST_TEST(pt.front().first == T("key1"));
579     BOOST_TEST(pt.back().first == T("key2"));
580 
581 }
582 
test_get_put(PTREE *)583 void test_get_put(PTREE *)
584 {
585 
586     typedef std::basic_string<CHTYPE> str_t;
587 
588     // Temporary storage
589     str_t tmp_string;
590     boost::optional<int> opt_int;
591     boost::optional<long> opt_long;
592     boost::optional<double> opt_double;
593     boost::optional<float> opt_float;
594     boost::optional<str_t> opt_string;
595     boost::optional<CHTYPE> opt_char;
596     boost::optional<bool> opt_bool;
597 
598     // Do insertions via put
599     PTREE pt;
600     PTREE &pt1 = pt.put(T("k1"), 1);
601     PTREE &pt2 = pt.put(T("k2.k"), 2.5);
602     PTREE &pt3 = pt.put(T("k3.k.k"), T("ala ma kota"));
603     PTREE &pt4 = pt.put(T("k4.k.k.k"), CHTYPE('c'));
604     PTREE &pt5 = pt.put(T("k5.k.k.k.f"), false);
605     PTREE &pt6 = pt.put(T("k5.k.k.k.t"), true);
606 
607     // Check instances count
608     //BOOST_TEST(PTREE::debug_get_instances_count() == 17);
609 
610     // Check if const char * version returns std::string
611     BOOST_TEST(typeid(pt.get_value(T(""))) == typeid(str_t));
612 
613     // Do extractions via get (throwing version)
614     BOOST_TEST(pt.get<int>(T("k1")) == 1);
615     BOOST_TEST(pt.get<long>(T("k1")) == 1);
616     BOOST_TEST(pt.get<double>(T("k2.k")) == 2.5);
617     BOOST_TEST(pt.get<float>(T("k2.k")) == 2.5f);
618     BOOST_TEST(pt.get<str_t>(T("k3.k.k")) == str_t(T("ala ma kota")));
619     BOOST_TEST(pt.get<CHTYPE>(T("k4.k.k.k")) == CHTYPE('c'));
620     BOOST_TEST(pt.get<bool>(T("k5.k.k.k.f")) == false);
621     BOOST_TEST(pt.get<bool>(T("k5.k.k.k.t")) == true);
622 
623     // Do extractions via get (default value version)
624     BOOST_TEST(pt.get(T("k1"), 0) == 1);
625     BOOST_TEST(pt.get(T("k1"), 0L) == 1);
626     BOOST_TEST(pt.get(T("k2.k"), 0.0) == 2.5);
627     BOOST_TEST(pt.get(T("k2.k"), 0.0f) == 2.5f);
628     BOOST_TEST(pt.get(T("k3.k.k"), str_t()) == str_t(T("ala ma kota")));
629     BOOST_TEST(pt.get(T("k3.k.k"), T("")) == T("ala ma kota"));
630     BOOST_TEST(pt.get(T("k4.k.k.k"), CHTYPE('\0')) == CHTYPE('c'));
631     BOOST_TEST(pt.get(T("k5.k.k.k.f"), true) == false);
632     BOOST_TEST(pt.get(T("k5.k.k.k.t"), false) == true);
633 
634     // Do extractions via get (optional version)
635     opt_int = pt.get_optional<int>(T("k1"));
636     BOOST_TEST(opt_int && *opt_int == 1);
637     opt_long = pt.get_optional<long>(T("k1"));
638     BOOST_TEST(opt_long && *opt_long == 1);
639     opt_double = pt.get_optional<double>(T("k2.k"));
640     BOOST_TEST(opt_double && *opt_double == 2.5);
641     opt_float = pt.get_optional<float>(T("k2.k"));
642     BOOST_TEST(opt_float && *opt_float == 2.5f);
643     opt_string = pt.get_optional<str_t>(T("k3.k.k"));
644     BOOST_TEST(opt_string && *opt_string == str_t(T("ala ma kota")));
645     opt_char = pt.get_optional<CHTYPE>(T("k4.k.k.k"));
646     BOOST_TEST(opt_char && *opt_char == CHTYPE('c'));
647     opt_bool = pt.get_optional<bool>(T("k5.k.k.k.f"));
648     BOOST_TEST(opt_bool && *opt_bool == false);
649     opt_bool = pt.get_optional<bool>(T("k5.k.k.k.t"));
650     BOOST_TEST(opt_bool && *opt_bool == true);
651 
652     // Do insertions via put_value
653     pt1.put_value(short(1));
654     pt2.put_value(2.5f);
655     pt3.put_value(str_t(T("ala ma kota")));
656     pt4.put_value(CHTYPE('c'));
657     pt5.put_value(false);
658     pt6.put_value(true);
659 
660     // Do extractions via get_value (throwing version)
661     BOOST_TEST(pt1.get_value<int>() == 1);
662     BOOST_TEST(pt1.get_value<long>() == 1);
663     BOOST_TEST(pt2.get_value<double>() == 2.5);
664     BOOST_TEST(pt2.get_value<float>() == 2.5f);
665     BOOST_TEST(pt3.get_value<str_t>() == str_t(T("ala ma kota")));
666     BOOST_TEST(pt4.get_value<CHTYPE>() == CHTYPE('c'));
667     BOOST_TEST(pt5.get_value<bool>() == false);
668     BOOST_TEST(pt6.get_value<bool>() == true);
669 
670     // Do extractions via get_value (default value version)
671     BOOST_TEST(pt1.get_value(0) == 1);
672     BOOST_TEST(pt1.get_value(0L) == 1);
673     BOOST_TEST(pt2.get_value(0.0) == 2.5);
674     BOOST_TEST(pt2.get_value(0.0f) == 2.5f);
675     BOOST_TEST(pt3.get_value(str_t()) == str_t(T("ala ma kota")));
676     BOOST_TEST(pt3.get_value(T("")) == T("ala ma kota"));
677     BOOST_TEST(pt4.get_value(CHTYPE('\0')) == CHTYPE('c'));
678     BOOST_TEST(pt5.get_value(true) == false);
679     BOOST_TEST(pt6.get_value(false) == true);
680 
681     // Do extractions via get_value (optional version)
682     opt_int = pt1.get_value_optional<int>();
683     BOOST_TEST(opt_int && *opt_int == 1);
684     opt_long = pt1.get_value_optional<long>();
685     BOOST_TEST(opt_long && *opt_long == 1);
686     opt_double = pt2.get_value_optional<double>();
687     BOOST_TEST(opt_double && *opt_double == 2.5);
688     opt_float = pt2.get_value_optional<float>();
689     BOOST_TEST(opt_float && *opt_float == 2.5f);
690     opt_string = pt3.get_value_optional<str_t>();
691     BOOST_TEST(opt_string && *opt_string == str_t(T("ala ma kota")));
692     opt_char = pt4.get_value_optional<CHTYPE>();
693     BOOST_TEST(opt_char && *opt_char == CHTYPE('c'));
694     opt_bool = pt5.get_value_optional<bool>();
695     BOOST_TEST(opt_bool && *opt_bool == false);
696     opt_bool = pt6.get_value_optional<bool>();
697     BOOST_TEST(opt_bool && *opt_bool == true);
698 
699     // Do incorrect extractions (throwing version)
700     try
701     {
702         pt.get<int>(T("k2.k.bogus.path"));
703         BOOST_ERROR("No required exception thrown");
704     }
705     catch (boost::property_tree::ptree_bad_path &) { }
706     catch (...)
707     {
708         BOOST_ERROR("Wrong exception type thrown");
709     }
710     try
711     {
712         pt.get<int>(T("k2.k"));
713         BOOST_ERROR("No required exception thrown");
714     }
715     catch (boost::property_tree::ptree_bad_data &) { }
716     catch (...)
717     {
718         BOOST_ERROR("Wrong exception type thrown");
719     }
720 
721     // Do incorrect extractions (default value version)
722     BOOST_TEST(pt.get(T("k2.k"), -7) == -7);
723     BOOST_TEST(pt.get(T("k3.k.k"), -7) == -7);
724     BOOST_TEST(pt.get(T("k4.k.k.k"), -7) == -7);
725 
726     // Do incorrect extractions (optional version)
727     BOOST_TEST(!pt.get_optional<int>(T("k2.k")));
728     BOOST_TEST(!pt.get_optional<int>(T("k3.k.k")));
729     BOOST_TEST(!pt.get_optional<int>(T("k4.k.k.k")));
730 
731     // Test multiple puts with the same key
732     {
733         PTREE pt;
734         pt.put(T("key"), 1);
735         BOOST_TEST(pt.get<int>(T("key")) == 1);
736         BOOST_TEST(pt.size() == 1);
737         pt.put(T("key"), 2);
738         BOOST_TEST(pt.get<int>(T("key")) == 2);
739         BOOST_TEST(pt.size() == 1);
740         pt.put(T("key.key.key"), 1);
741         PTREE &child = pt.get_child(T("key.key"));
742         BOOST_TEST(pt.get<int>(T("key.key.key")) == 1);
743         BOOST_TEST(child.size() == 1);
744         BOOST_TEST(child.count(T("key")) == 1);
745         pt.put(T("key.key.key"), 2);
746         BOOST_TEST(pt.get<int>(T("key.key.key")) == 2);
747         BOOST_TEST(child.size() == 1);
748         BOOST_TEST(child.count(T("key")) == 1);
749     }
750 
751     // Test multiple puts with the same key
752     {
753         PTREE pt;
754         pt.put(T("key"), 1);
755         BOOST_TEST(pt.get<int>(T("key")) == 1);
756         BOOST_TEST(pt.size() == 1);
757         pt.put(T("key"), 2);
758         BOOST_TEST(pt.get<int>(T("key")) == 2);
759         BOOST_TEST(pt.size() == 1);
760         pt.put(T("key.key.key"), 1);
761         PTREE &child = pt.get_child(T("key.key"));
762         BOOST_TEST(child.size() == 1);
763         BOOST_TEST(child.count(T("key")) == 1);
764         pt.add(T("key.key.key"), 2);
765         BOOST_TEST(child.size() == 2);
766         BOOST_TEST(child.count(T("key")) == 2);
767     }
768 
769     // Test that put does not destroy children
770     {
771         PTREE pt;
772         pt.put(T("key1"), 1);
773         pt.put(T("key1.key2"), 2);
774         BOOST_TEST(pt.get<int>(T("key1"), 0) == 1);
775         BOOST_TEST(pt.get<int>(T("key1.key2"), 0) == 2);
776         pt.put(T("key1"), 2);
777         BOOST_TEST(pt.get<int>(T("key1"), 0) == 2);
778         BOOST_TEST(pt.get<int>(T("key1.key2"), 0) == 2);
779     }
780 
781     // Test that get of single character that is whitespace works
782     {
783         PTREE pt;
784         pt.put_value(T(' '));
785         CHTYPE ch = pt.get_value<CHTYPE>();
786         BOOST_TEST(ch == T(' '));
787     }
788 
789     // Test that get of non-char value with trailing and leading whitespace works
790     {
791         PTREE pt;
792         pt.put_value(T(" \t\n99 \t\n"));
793         BOOST_TEST(pt.get_value<int>(0) == 99);
794     }
795 
796 }
797 
test_get_child_put_child(PTREE *)798 void test_get_child_put_child(PTREE *)
799 {
800     PTREE pt(T("ala ma kota"));
801 
802     // Do insertions via put_child
803     PTREE pt1, pt2, pt3;
804     pt1.put_child(T("k1"), PTREE());
805     pt1.put_child(T("k2.k"), PTREE());
806     pt2.put_child(T("k1"), pt);
807     pt2.put_child(T("k2.k"), pt);
808 
809     // Const references to test const versions of methods
810     const PTREE &cpt1 = pt1, &cpt2 = pt2;
811 
812     // Do correct extractions via get_child (throwing version)
813     BOOST_TEST(pt1.get_child(T("k1")).empty());
814     BOOST_TEST(pt1.get_child(T("k2.k")).empty());
815     BOOST_TEST(pt2.get_child(T("k1")) == pt);
816     BOOST_TEST(pt2.get_child(T("k2.k")) == pt);
817     BOOST_TEST(cpt1.get_child(T("k1")).empty());
818     BOOST_TEST(cpt1.get_child(T("k2.k")).empty());
819     BOOST_TEST(cpt2.get_child(T("k1")) == pt);
820     BOOST_TEST(cpt2.get_child(T("k2.k")) == pt);
821 
822     // Do correct extractions via get_child (default value version)
823     BOOST_TEST(pt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def")));
824     BOOST_TEST(pt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def")));
825     BOOST_TEST(pt2.get_child(T("k1"), PTREE(T("def"))) == pt);
826     BOOST_TEST(pt2.get_child(T("k2.k"), PTREE(T("def"))) == pt);
827     BOOST_TEST(cpt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def")));
828     BOOST_TEST(cpt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def")));
829     BOOST_TEST(cpt2.get_child(T("k1"), PTREE(T("def"))) == pt);
830     BOOST_TEST(cpt2.get_child(T("k2.k"), PTREE(T("def"))) == pt);
831 
832     // Do correct extractions via get_child (optional version)
833     boost::optional<PTREE &> opt;
834     boost::optional<const PTREE &> copt;
835     opt = pt1.get_child_optional(T("k1"));
836     BOOST_TEST(opt);
837     opt = pt1.get_child_optional(T("k2.k"));
838     BOOST_TEST(opt);
839     opt = pt2.get_child_optional(T("k1"));
840     BOOST_TEST(opt && *opt == pt);
841     opt = pt2.get_child_optional(T("k2.k"));
842     BOOST_TEST(opt && *opt == pt);
843     copt = cpt1.get_child_optional(T("k1"));
844     BOOST_TEST(copt);
845     copt = cpt1.get_child_optional(T("k2.k"));
846     BOOST_TEST(copt);
847     copt = cpt2.get_child_optional(T("k1"));
848     BOOST_TEST(copt && *copt == pt);
849     copt = cpt2.get_child_optional(T("k2.k"));
850     BOOST_TEST(copt && *copt == pt);
851 
852     // Do incorrect extractions via get_child (throwing version)
853     try
854     {
855         pt.get_child(T("k2.k.bogus.path"));
856         BOOST_ERROR("No required exception thrown");
857     }
858     catch (boost::property_tree::ptree_bad_path &) { }
859     catch (...)
860     {
861         BOOST_ERROR("Wrong exception type thrown");
862     }
863 
864     // Do incorrect extractions via get_child (default value version)
865     BOOST_TEST(&pt.get_child(T("k2.k.bogus.path"), pt3) == &pt3);
866 
867     // Do incorrect extractions via get_child (optional version)
868     BOOST_TEST(!pt.get_child_optional(T("k2.k.bogus.path")));
869 
870     // Test multiple puts with the same key
871     {
872         PTREE pt, tmp1(T("data1")), tmp2(T("data2"));
873         pt.put_child(T("key"), tmp1);
874         BOOST_TEST(pt.get_child(T("key")) == tmp1);
875         BOOST_TEST(pt.size() == 1);
876         pt.put_child(T("key"), tmp2);
877         BOOST_TEST(pt.get_child(T("key")) == tmp2);
878         BOOST_TEST(pt.size() == 1);
879         pt.put_child(T("key.key.key"), tmp1);
880         PTREE &child = pt.get_child(T("key.key"));
881         BOOST_TEST(child.size() == 1);
882         pt.put_child(T("key.key.key"), tmp2);
883         BOOST_TEST(child.size() == 1);
884     }
885 
886     // Test multiple adds with the same key
887     {
888         PTREE pt, tmp1(T("data1")), tmp2(T("data2"));
889         pt.add_child(T("key"), tmp1);
890         BOOST_TEST(pt.size() == 1);
891         pt.add_child(T("key"), tmp2);
892         BOOST_TEST(pt.size() == 2);
893         BOOST_TEST(pt.count(T("key")) == 2);
894         pt.add_child(T("key.key.key"), tmp1);
895         PTREE &child = pt.get_child(T("key.key"));
896         BOOST_TEST(child.size() == 1);
897         BOOST_TEST(child.count(T("key")) == 1);
898         pt.add_child(T("key.key.key"), tmp2);
899         BOOST_TEST(child.size() == 2);
900         BOOST_TEST(child.count(T("key")) == 2);
901     }
902 
903     // Test assigning child to tree
904     {
905         PTREE pt;
906         pt.put(T("foo.bar"), T("baz"));
907         pt = pt.get_child(T("foo"));
908         BOOST_TEST(pt.size() == 1);
909         BOOST_TEST(pt.get< std::basic_string<CHTYPE> >(T("bar")) == T("baz"));
910     }
911 
912 }
913 
test_equal_range(PTREE *)914 void test_equal_range(PTREE *)
915 {
916     PTREE pt;
917     pt.add_child(T("k1"), PTREE());
918     pt.add_child(T("k2"), PTREE());
919     pt.add_child(T("k1"), PTREE());
920     pt.add_child(T("k3"), PTREE());
921     pt.add_child(T("k1"), PTREE());
922     pt.add_child(T("k2"), PTREE());
923 
924     BOOST_TEST(boost::distance(pt.equal_range(T("k1"))) == 3);
925     BOOST_TEST(boost::distance(pt.equal_range(T("k2"))) == 2);
926     BOOST_TEST(boost::distance(pt.equal_range(T("k3"))) == 1);
927 }
928 
test_path_separator(PTREE *)929 void test_path_separator(PTREE *)
930 {
931 
932     typedef PTREE::path_type path;
933 
934     // Check instances count
935     //BOOST_TEST(PTREE::debug_get_instances_count() == 0);
936 
937     // Do insertions
938     PTREE pt;
939     pt.put(T("key1"), T("1"));
940     pt.put(T("key2.key"), T("2"));
941     pt.put(T("key3.key.key"), T("3"));
942     pt.put(path(T("key4"), CHTYPE('/')), T("4"));
943     pt.put(path(T("key5/key"), CHTYPE('/')), T("5"));
944     pt.put(path(T("key6/key/key"), CHTYPE('/')), T("6"));
945 
946     // Check instances count
947     //BOOST_TEST(PTREE::debug_get_instances_count() == 13);
948 
949     // Do correct extractions
950     BOOST_TEST(pt.get(T("key1"), 0) == 1);
951     BOOST_TEST(pt.get(T("key2.key"), 0) == 2);
952     BOOST_TEST(pt.get(T("key3.key.key"), 0) == 3);
953     BOOST_TEST(pt.get(path(T("key4"), CHTYPE('/')), 0) == 4);
954     BOOST_TEST(pt.get(path(T("key5/key"), CHTYPE('/')), 0) == 5);
955     BOOST_TEST(pt.get(path(T("key6/key/key"), CHTYPE('/')), 0) == 6);
956 
957     // Do incorrect extractions
958     BOOST_TEST(pt.get(T("key2/key"), 0) == 0);
959     BOOST_TEST(pt.get(T("key3/key/key"), 0) == 0);
960     BOOST_TEST(pt.get(path(T("key5.key"), CHTYPE('/')), 0) == 0);
961     BOOST_TEST(pt.get(path(T("key6.key.key"), CHTYPE('/')), 0) == 0);
962 
963 }
964 
test_path(PTREE *)965 void test_path(PTREE *)
966 {
967 
968     typedef PTREE::path_type path;
969 
970     // Insert
971     PTREE pt;
972     pt.put(T("key1.key2.key3"), 1);
973 
974     // Test operator /=
975     {
976         path p;
977         p /= T("key1"); p /= T("key2"); p /= T("key3");
978         BOOST_TEST(pt.get<int>(p, 0) == 1);
979     }
980 
981     // Test operator /=
982     {
983         path p(T("key1"));
984         p /= T("key2.key3");
985         BOOST_TEST(pt.get<int>(p, 0) == 1);
986     }
987 
988     // Test operator /=
989     {
990         path p;
991         path p1(T("key1.key2"));
992         path p2(T("key3"));
993         p /= p1;
994         p /= p2;
995         BOOST_TEST(pt.get<int>(p, 0) == 1);
996     }
997 
998     // Test operator /
999     {
1000         path p = path(T("key1")) / T("key2.key3");
1001         BOOST_TEST(pt.get<int>(p, 0) == 1);
1002     }
1003 
1004     // Test operator /
1005     {
1006         path p = T("key1.key2") / path(T("key3"));
1007         BOOST_TEST(pt.get<int>(p, 0) == 1);
1008     }
1009 
1010 }
1011 
test_precision(PTREE *)1012 void test_precision(PTREE *)
1013 {
1014 
1015     typedef double real;
1016 
1017     // Quite precise PI value
1018     real pi = real(3.1415926535897932384626433832795028841971);
1019 
1020     // Put and get
1021     PTREE pt;
1022     pt.put_value(pi);
1023     real pi2 = pt.get_value<real>();
1024 
1025     // Test if precision is "good enough", i.e. if stream precision increase worked
1026     using namespace std;
1027     real error = abs(pi - pi2) *
1028         pow(real(numeric_limits<real>::radix),
1029             real(numeric_limits<real>::digits));
1030     BOOST_TEST(error < 100);
1031 
1032 }
1033 
test_locale(PTREE *)1034 void test_locale(PTREE *)
1035 {
1036     typedef boost::property_tree::translator_between<
1037         std::basic_string<CHTYPE>, double>::type translator;
1038     try
1039     {
1040 
1041         // Write strings in english and french locales
1042         PTREE pt;
1043 #ifdef BOOST_WINDOWS
1044         std::locale loc_english("english");
1045         std::locale loc_french("french");
1046 #else
1047         std::locale loc_english("en_GB");
1048         std::locale loc_french("fr_FR");
1049 #endif
1050         pt.put(T("english"), 1.234, translator(loc_english));
1051         pt.put(T("french"), 1.234, translator(loc_french));
1052 
1053         // Test contents
1054         BOOST_TEST(pt.get<PTREE::data_type>(T("english")) == T("1.234"));
1055         BOOST_TEST(pt.get<PTREE::data_type>(T("french")) == T("1,234"));
1056 
1057     }
1058     catch (boost::property_tree::ptree_error &)
1059     {
1060         throw;
1061     }
1062     catch (std::runtime_error &e)
1063     {
1064         std::cerr << "Required locale not supported by the platform. "
1065                      "Skipping locale tests (caught std::runtime_error with message " <<
1066                      e.what() << ").\n";
1067     }
1068 
1069 }
1070 
test_custom_data_type(PTREE *)1071 void test_custom_data_type(PTREE *)
1072 {
1073 
1074     typedef std::basic_string<CHTYPE> Str;
1075     typedef PTREE::key_compare Comp;
1076 
1077     // Property_tree with boost::any as data type
1078     typedef boost::property_tree::basic_ptree<Str, boost::any, Comp> my_ptree;
1079     my_ptree pt;
1080 
1081     // Put/get int value
1082     pt.put(T("int value"), 3);
1083     int int_value = pt.get<int>(T("int value"));
1084     BOOST_TEST(int_value == 3);
1085 
1086     // Put/get string value
1087     pt.put<std::basic_string<CHTYPE> >(T("string value"), T("foo bar"));
1088     std::basic_string<CHTYPE> string_value = pt.get<std::basic_string<CHTYPE> >(T("string value"));
1089     BOOST_TEST(string_value == T("foo bar"));
1090 
1091     // Put/get list<int> value
1092     int list_data[] = { 1, 2, 3, 4, 5 };
1093     pt.put<std::list<int> >(T("list value"), std::list<int>(list_data, list_data + sizeof(list_data) / sizeof(*list_data)));
1094     std::list<int> list_value = pt.get<std::list<int> >(T("list value"));
1095     BOOST_TEST(list_value.size() == 5);
1096     BOOST_TEST(list_value.front() == 1);
1097     BOOST_TEST(list_value.back() == 5);
1098 
1099 }
1100 
test_empty_size_max_size(PTREE *)1101 void test_empty_size_max_size(PTREE *)
1102 {
1103 
1104     PTREE pt;
1105     BOOST_TEST(pt.max_size());
1106     BOOST_TEST(pt.empty());
1107     BOOST_TEST(pt.size() == 0);
1108 
1109     pt.put(T("test1"), 1);
1110     BOOST_TEST(pt.max_size());
1111     BOOST_TEST(!pt.empty());
1112     BOOST_TEST(pt.size() == 1);
1113 
1114     pt.put(T("test2"), 2);
1115     BOOST_TEST(pt.max_size());
1116     BOOST_TEST(!pt.empty());
1117     BOOST_TEST(pt.size() == 2);
1118 
1119 }
1120 
test_ptree_bad_path(PTREE *)1121 void test_ptree_bad_path(PTREE *)
1122 {
1123 
1124     PTREE pt;
1125 
1126     try
1127     {
1128         pt.get<int>(T("non.existent.path"));
1129     }
1130     catch (boost::property_tree::ptree_bad_path &e)
1131     {
1132         PTREE::path_type path = e.path<PTREE::path_type>();
1133         std::string what = e.what();
1134         BOOST_TEST(what.find("non.existent.path") != std::string::npos);
1135         return;
1136     }
1137 
1138     BOOST_ERROR("No required exception thrown");
1139 
1140 }
1141 
test_ptree_bad_data(PTREE *)1142 void test_ptree_bad_data(PTREE *)
1143 {
1144 
1145     PTREE pt;
1146     pt.put_value("non convertible to int");
1147 
1148     try
1149     {
1150         pt.get_value<int>();
1151     }
1152     catch (boost::property_tree::ptree_bad_data &e)
1153     {
1154         PTREE::data_type data = e.data<PTREE::data_type>();
1155         std::string what = e.what();
1156         // FIXME: Bring back what translation or make it more clear that it
1157         // doesn't work.
1158         //BOOST_TEST(what.find("non convertible to int") != std::string::npos);
1159         return;
1160     }
1161 
1162     BOOST_ERROR("No required exception thrown");
1163 }
1164 
test_serialization(PTREE *)1165 void test_serialization(PTREE *)
1166 {
1167 
1168     // Prepare test tree
1169     PTREE pt;
1170     pt.put_value(1);
1171     pt.put(T("key1"), 3);
1172     pt.put(T("key1.key11)"), 3.3);
1173     pt.put(T("key1.key12"), T("foo"));
1174     pt.put(T("key2"), true);
1175     pt.put(T("key2.key21.key211.key2111.key21111"), T("super deep!"));
1176     pt.put_child(T("empty"), PTREE());
1177     pt.put(T("loooooong"), PTREE::data_type(10000, CHTYPE('a')));
1178 
1179     // Endforce const for input
1180     const PTREE &pt1 = pt;
1181 
1182     // Test text archives
1183     {
1184         std::stringstream stream;
1185         boost::archive::text_oarchive oa(stream);
1186         oa & pt1;
1187         boost::archive::text_iarchive ia(stream);
1188         PTREE pt2;
1189         ia & pt2;
1190         BOOST_TEST(pt1 == pt2);
1191     }
1192 
1193     // Test binary archives
1194     {
1195         std::stringstream stream;
1196         boost::archive::binary_oarchive oa(stream);
1197         oa & pt1;
1198         boost::archive::binary_iarchive ia(stream);
1199         PTREE pt2;
1200         ia & pt2;
1201         BOOST_TEST(pt1 == pt2);
1202     }
1203 
1204     // Test XML archives
1205     {
1206         std::stringstream stream;
1207 
1208         {
1209             boost::archive::xml_oarchive oa(stream);
1210             oa & boost::serialization::make_nvp("pt", pt1);
1211         }
1212 
1213         PTREE pt2;
1214 
1215         {
1216             boost::archive::xml_iarchive ia(stream);
1217             ia & boost::serialization::make_nvp("pt", pt2);
1218         }
1219 
1220         BOOST_TEST(pt1 == pt2);
1221     }
1222 
1223 }
1224 
test_bool(PTREE *)1225 void test_bool(PTREE *)
1226 {
1227 
1228     // Prepare test tree
1229     PTREE pt;
1230     pt.put(T("bool.false.1"), false);
1231     pt.put(T("bool.false.2"), T("0"));
1232     pt.put(T("bool.true.1"), true);
1233     pt.put(T("bool.true.2"), 1);
1234     pt.put(T("bool.invalid.1"), T(""));
1235     pt.put(T("bool.invalid.2"), T("tt"));
1236     pt.put(T("bool.invalid.3"), T("ff"));
1237     pt.put(T("bool.invalid.4"), T("2"));
1238     pt.put(T("bool.invalid.5"), T("-1"));
1239 
1240     // Test false
1241     for (PTREE::iterator it = pt.get_child(T("bool.false")).begin(); it != pt.get_child(T("bool.false")).end(); ++it)
1242         BOOST_TEST(it->second.get_value<bool>() == false);
1243 
1244     // Test true
1245     for (PTREE::iterator it = pt.get_child(T("bool.true")).begin(); it != pt.get_child(T("bool.true")).end(); ++it)
1246         BOOST_TEST(it->second.get_value<bool>() == true);
1247 
1248     // Test invalid
1249     for (PTREE::iterator it = pt.get_child(T("bool.invalid")).begin(); it != pt.get_child(T("bool.invalid")).end(); ++it)
1250     {
1251         BOOST_TEST(it->second.get_value<bool>(false) == false);
1252         BOOST_TEST(it->second.get_value<bool>(true) == true);
1253     }
1254 
1255 }
1256 
test_char(PTREE *)1257 void test_char(PTREE *)
1258 {
1259     typedef signed char schar;
1260     typedef unsigned char uchar;
1261 
1262     // Prepare test tree
1263     PTREE pt;
1264 #if WIDECHAR == 0
1265     pt.put(T("char"), char('A'));
1266 #endif
1267     pt.put(T("signed char"), static_cast<schar>('A'));
1268     pt.put(T("unsigned char"), static_cast<uchar>('A'));
1269     pt.put(T("signed char min"), (std::numeric_limits<schar>::min)());
1270     pt.put(T("signed char max"), (std::numeric_limits<schar>::max)());
1271     pt.put(T("signed char underflow"),
1272            static_cast<int>((std::numeric_limits<schar>::min)()) - 1);
1273     pt.put(T("signed char overflow"),
1274            static_cast<int>((std::numeric_limits<schar>::max)()) + 1);
1275     pt.put(T("unsigned char min"), (std::numeric_limits<uchar>::min)());
1276     pt.put(T("unsigned char max"), (std::numeric_limits<uchar>::max)());
1277     pt.put(T("unsigned char overflow"),
1278            static_cast<unsigned>((std::numeric_limits<uchar>::max)()) + 1);
1279 
1280     // Verify normal conversions
1281 #if WIDECHAR == 0
1282     BOOST_TEST(pt.get<char>(T("char")) == 'A');
1283 #endif
1284     BOOST_TEST(pt.get<schar>(T("signed char")) == static_cast<schar>('A'));
1285     BOOST_TEST(pt.get<uchar>(T("unsigned char")) == static_cast<uchar>('A'));
1286 
1287     // Verify that numbers are saved for signed and unsigned char
1288     BOOST_TEST(pt.get<int>(T("signed char")) == int('A'));
1289     BOOST_TEST(pt.get<int>(T("unsigned char")) == int('A'));
1290 
1291     // Verify ranges
1292     BOOST_TEST(pt.get<schar>(T("signed char min")) ==
1293         (std::numeric_limits<schar>::min)());
1294     BOOST_TEST(pt.get<schar>(T("signed char max")) ==
1295         (std::numeric_limits<schar>::max)());
1296     BOOST_TEST(pt.get<uchar>(T("unsigned char min")) ==
1297         (std::numeric_limits<uchar>::min)());
1298     BOOST_TEST(pt.get<uchar>(T("unsigned char max")) ==
1299         (std::numeric_limits<uchar>::max)());
1300 
1301     // Check that out-of-range throws.
1302     try {
1303         pt.get<schar>(T("signed char underflow"));
1304         BOOST_ERROR("expected ptree_bad_data, but nothing was thrown");
1305     } catch (boost::property_tree::ptree_bad_data&) {
1306     } catch (...) {
1307         BOOST_ERROR("expected ptree_bad_data, but something else was thrown");
1308     }
1309     try {
1310         pt.get<schar>(T("signed char overflow"));
1311         BOOST_ERROR("expected ptree_bad_data, but nothing was thrown");
1312     } catch (boost::property_tree::ptree_bad_data&) {
1313     } catch (...) {
1314         BOOST_ERROR("expected ptree_bad_data, but something else was thrown");
1315     }
1316     try {
1317         pt.get<uchar>(T("unsigned char overflow"));
1318         BOOST_ERROR("expected ptree_bad_data, but nothing was thrown");
1319     } catch (boost::property_tree::ptree_bad_data&) {
1320     } catch (...) {
1321         BOOST_ERROR("expected ptree_bad_data, but something else was thrown");
1322     }
1323 }
1324 
test_float(PTREE *)1325 void test_float(PTREE*)
1326 {
1327     const double difficult = -183.12345000098765e-10;
1328     PTREE pt;
1329     pt.put(T("num"), difficult);
1330     double result = pt.get<double>(T("num"));
1331 
1332     BOOST_TEST(!(result < difficult || result > difficult));
1333 }
1334 
test_sort(PTREE *)1335 void test_sort(PTREE *)
1336 {
1337   PTREE pt;
1338   pt.put(T("one"), T("v1"));
1339   pt.put(T("two"), T("v2"));
1340   pt.put(T("three"), T("v3"));
1341   pt.put(T("four"), T("v4"));
1342 
1343   pt.sort();
1344 
1345   PTREE::iterator it = pt.begin();
1346   BOOST_TEST(std::distance(it, pt.end()) == 4);
1347   BOOST_TEST(it->first == T("four"));
1348   BOOST_TEST(it->second.data() == T("v4"));
1349   ++it;
1350   BOOST_TEST(it->first == T("one"));
1351   BOOST_TEST(it->second.data() == T("v1"));
1352   ++it;
1353   BOOST_TEST(it->first == T("three"));
1354   BOOST_TEST(it->second.data() == T("v3"));
1355   ++it;
1356   BOOST_TEST(it->first == T("two"));
1357   BOOST_TEST(it->second.data() == T("v2"));
1358 }
1359 
test_leaks(PTREE *)1360 void test_leaks(PTREE *)
1361 {
1362     //BOOST_TEST(PTREE::debug_get_instances_count() == 0);
1363 }
1364