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

source code of boost/libs/property_tree/test/test_property_tree.hpp