1 | // |
2 | // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) |
3 | // Copyright (c) 2022 Alexander Grund |
4 | // |
5 | // Distributed under the Boost Software License, Version 1.0. |
6 | // https://www.boost.org/LICENSE_1_0.txt |
7 | |
8 | #include "../src/boost/locale/shared/ios_prop.hpp" |
9 | #include "boostLocale/test/unit_test.hpp" |
10 | #include <locale> |
11 | #include <sstream> |
12 | |
13 | int counter = 0; |
14 | int imbued = 0; |
15 | struct test_property { |
16 | explicit test_property(int xx = -1) : x(xx) { counter++; } |
17 | test_property(const test_property& other) |
18 | { |
19 | counter++; |
20 | x = other.x; |
21 | } |
22 | test_property& operator=(const test_property&) = default; |
23 | ~test_property() { counter--; } |
24 | void on_imbue() { imbued++; } |
25 | |
26 | int x; |
27 | }; |
28 | typedef boost::locale::impl::ios_prop<test_property> prop_type; |
29 | |
30 | struct init { |
31 | init() { prop_type::global_init(); } |
32 | }; |
33 | |
34 | void test_main(int /*argc*/, char** /*argv*/) |
35 | { |
36 | // Test get() default constructs the property if it does not exist or returns the existing one |
37 | { |
38 | std::stringstream ss; |
39 | TEST_EQ(prop_type::get(ss).x, -1); |
40 | TEST_EQ(counter, 1); |
41 | prop_type::get(ios&: ss).x = 42; |
42 | TEST_EQ(prop_type::get(ss).x, 42); |
43 | TEST_EQ(counter, 1); |
44 | } |
45 | TEST_EQ(counter, 0); |
46 | { |
47 | std::stringstream ss; |
48 | prop_type::get(ios&: ss).x = 1; |
49 | { |
50 | std::stringstream ss2; |
51 | TEST_EQ(counter, 1); |
52 | ss2.copyfmt(rhs: ss); |
53 | TEST_EQ(counter, 2); |
54 | TEST_EQ(prop_type::get(ss).x, 1); |
55 | TEST_EQ(prop_type::get(ss2).x, 1); |
56 | // Check that both are distinct copies |
57 | prop_type::get(ios&: ss2).x = 2; |
58 | TEST_EQ(prop_type::get(ss).x, 1); |
59 | TEST_EQ(prop_type::get(ss2).x, 2); // Only 2nd is changed |
60 | // Imbue on 2nd calls on_imbue once |
61 | TEST_EQ(imbued, 0); |
62 | ss2.imbue(loc: std::locale::classic()); |
63 | TEST_EQ(imbued, 1); |
64 | // Copy again over existing |
65 | ss2.copyfmt(rhs: ss); |
66 | TEST_EQ(counter, 2); |
67 | TEST_EQ(prop_type::get(ss).x, 1); |
68 | TEST_EQ(prop_type::get(ss2).x, 1); // Copied |
69 | prop_type::get(ios&: ss2).x = 2; |
70 | TEST_EQ(prop_type::get(ss).x, 1); |
71 | TEST_EQ(prop_type::get(ss2).x, 2); // Only this changed |
72 | } |
73 | // Copy from unset removes the property |
74 | { |
75 | std::stringstream ss2; |
76 | TEST_EQ(prop_type::get(ss).x, 1); |
77 | TEST_EQ(counter, 1); |
78 | ss.copyfmt(rhs: ss2); |
79 | TEST_EQ(counter, 0); |
80 | // All are default constructed, distinct instances |
81 | TEST_EQ(prop_type::get(ss).x, -1); |
82 | TEST_EQ(prop_type::get(ss2).x, -1); |
83 | prop_type::get(ios&: ss2).x = 2; |
84 | TEST_EQ(prop_type::get(ss).x, -1); |
85 | TEST_EQ(prop_type::get(ss2).x, 2); |
86 | TEST_EQ(counter, 2); |
87 | } |
88 | } |
89 | TEST_EQ(counter, 0); |
90 | } |
91 | |