• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright (c) 2012 Artyom Beilis (Tonkikh)
3 //  Copyright (c) 2019-2020 Alexander Grund
4 //
5 //  Distributed under the Boost Software License, Version 1.0. (See
6 //  accompanying file LICENSE or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 //
9 
10 #include <boost/nowide/stackstring.hpp>
11 #include <iostream>
12 #include <vector>
13 
14 #include "test.hpp"
15 #include "test_sets.hpp"
16 
17 #if defined(BOOST_MSVC) && BOOST_MSVC < 1700
18 #pragma warning(disable : 4428) // universal-character-name encountered in source
19 #endif
20 
21 template<typename CharOut, typename CharIn, size_t BufferSize>
22 class test_basic_stackstring : public boost::nowide::basic_stackstring<CharOut, CharIn, BufferSize>
23 {
24 public:
25     typedef boost::nowide::basic_stackstring<CharOut, CharIn, BufferSize> parent;
26 
27     using parent::parent;
28     using parent::uses_stack_memory;
uses_heap_memory() const29     bool uses_heap_memory() const
30     {
31         return !uses_stack_memory() && this->get();
32     }
33 };
34 
35 typedef test_basic_stackstring<wchar_t, char, 256> test_wstackstring;
36 typedef test_basic_stackstring<char, wchar_t, 256> test_stackstring;
37 
stackstring_to_wide(const std::string & s)38 std::wstring stackstring_to_wide(const std::string& s)
39 {
40     const test_wstackstring ss(s.c_str());
41     TEST(ss.uses_stack_memory());
42     return ss.get();
43 }
44 
stackstring_to_narrow(const std::wstring & s)45 std::string stackstring_to_narrow(const std::wstring& s)
46 {
47     const test_stackstring ss(s.c_str());
48     TEST(ss.uses_stack_memory());
49     return ss.get();
50 }
51 
heap_stackstring_to_wide(const std::string & s)52 std::wstring heap_stackstring_to_wide(const std::string& s)
53 {
54     const test_basic_stackstring<wchar_t, char, 1> ss(s.c_str());
55     TEST(ss.uses_heap_memory() || s.empty());
56     return ss.get();
57 }
58 
heap_stackstring_to_narrow(const std::wstring & s)59 std::string heap_stackstring_to_narrow(const std::wstring& s)
60 {
61     const test_basic_stackstring<char, wchar_t, 1> ss(s.c_str());
62     TEST(ss.uses_heap_memory() || s.empty());
63     return ss.get();
64 }
65 
test_main(int,char **,char **)66 void test_main(int, char**, char**)
67 {
68     std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
69     std::wstring whello = boost::nowide::widen(hello);
70     const wchar_t* wempty = L"";
71 
72     {
73         std::cout << "-- Default constructed string is NULL" << std::endl;
74         const boost::nowide::short_stackstring s;
75         TEST(s.get() == NULL);
76     }
77     {
78         std::cout << "-- NULL ptr passed to ctor results in NULL" << std::endl;
79         const boost::nowide::short_stackstring s(NULL);
80         TEST(s.get() == NULL);
81         const boost::nowide::short_stackstring s2(NULL, NULL);
82         TEST(s2.get() == NULL);
83     }
84     {
85         std::cout << "-- NULL ptr passed to convert results in NULL" << std::endl;
86         boost::nowide::short_stackstring s(L"foo");
87         TEST(s.get() == std::string("foo"));
88         s.convert(NULL);
89         TEST(s.get() == NULL);
90         boost::nowide::short_stackstring s2(L"foo");
91         TEST(s2.get() == std::string("foo"));
92         s2.convert(NULL, NULL);
93         TEST(s2.get() == NULL);
94     }
95     {
96         std::cout << "-- An empty string is accepted" << std::endl;
97         const boost::nowide::short_stackstring s(wempty);
98         TEST(s.get());
99         TEST(s.get() == std::string());
100         const boost::nowide::short_stackstring s2(wempty, wempty);
101         TEST(s2.get());
102         TEST(s2.get() == std::string());
103     }
104     {
105         std::cout << "-- An empty string is accepted" << std::endl;
106         boost::nowide::short_stackstring s, s2;
107         TEST(s.convert(wempty));
108         TEST(s.get() == std::string());
109         TEST(s2.convert(wempty, wempty));
110         TEST(s2.get() == std::string());
111     }
112     {
113         std::cout << "-- Will be put on heap" << std::endl;
114         test_basic_stackstring<wchar_t, char, 3> sw;
115         TEST(sw.convert(hello.c_str()));
116         TEST(sw.uses_heap_memory());
117         TEST(sw.get() == whello);
118         TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
119         TEST(sw.uses_heap_memory());
120         TEST(sw.get() == whello);
121     }
122     {
123         std::cout << "-- Will be put on stack" << std::endl;
124         test_basic_stackstring<wchar_t, char, 40> sw;
125         TEST(sw.convert(hello.c_str()));
126         TEST(sw.uses_stack_memory());
127         TEST(sw.get() == whello);
128         TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
129         TEST(sw.uses_stack_memory());
130         TEST(sw.get() == whello);
131     }
132     {
133         std::cout << "-- Will be put on heap" << std::endl;
134         test_basic_stackstring<char, wchar_t, 3> sw;
135         TEST(sw.convert(whello.c_str()));
136         TEST(sw.uses_heap_memory());
137         TEST(sw.get() == hello);
138         TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
139         TEST(sw.uses_heap_memory());
140         TEST(sw.get() == hello);
141     }
142     {
143         std::cout << "-- Will be put on stack" << std::endl;
144         test_basic_stackstring<char, wchar_t, 40> sw;
145         TEST(sw.convert(whello.c_str()));
146         TEST(sw.uses_stack_memory());
147         TEST(sw.get() == hello);
148         TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
149         TEST(sw.uses_stack_memory());
150         TEST(sw.get() == hello);
151     }
152     {
153         typedef test_basic_stackstring<wchar_t, char, 6> stackstring;
154         const std::wstring heapVal = L"heapValue";
155         const std::wstring stackVal = L"stack";
156         const stackstring heap(boost::nowide::narrow(heapVal).c_str());
157         const stackstring stack(boost::nowide::narrow(stackVal).c_str());
158         TEST(heap.uses_heap_memory());
159         TEST(stack.uses_stack_memory());
160 
161         {
162             stackstring sw2(heap), sw3, sEmpty;
163             sw3 = heap;
164             TEST(sw2.get() == heapVal);
165             TEST(sw3.get() == heapVal);
166             // Self assign avoiding clang self-assign-overloaded warning
167             sw3 = static_cast<const stackstring&>(sw3); //-V570
168             TEST(sw3.get() == heapVal);
169             // Assign empty
170             sw3 = sEmpty; //-V820
171             TEST(sw3.get() == NULL);
172         }
173         {
174             stackstring sw2(stack), sw3, sEmpty;
175             sw3 = stack;
176             TEST(sw2.get() == stackVal);
177             TEST(sw3.get() == stackVal);
178             // Self assign avoiding clang self-assign-overloaded warning
179             sw3 = static_cast<const stackstring&>(sw3); //-V570
180             TEST(sw3.get() == stackVal);
181             // Assign empty
182             sw3 = sEmpty; //-V820
183             TEST(sw3.get() == NULL);
184         }
185         {
186             stackstring sw2(stack);
187             sw2 = heap;
188             TEST(sw2.get() == heapVal);
189         }
190         {
191             stackstring sw2(heap);
192             sw2 = stack;
193             TEST(sw2.get() == stackVal);
194         }
195         {
196             stackstring sw2(heap), sw3(stack), sEmpty1, sEmpty2;
197             swap(sw2, sw3);
198             TEST(sw2.get() == stackVal);
199             TEST(sw3.get() == heapVal);
200             swap(sw2, sw3);
201             TEST(sw2.get() == heapVal);
202             TEST(sw3.get() == stackVal);
203             swap(sw2, sEmpty1);
204             TEST(sEmpty1.get() == heapVal);
205             TEST(sw2.get() == NULL);
206             swap(sw3, sEmpty2);
207             TEST(sEmpty2.get() == stackVal);
208             TEST(sw3.get() == NULL);
209         }
210         {
211             stackstring sw2(heap), sw3(heap);
212             sw3.get()[0] = 'z';
213             const std::wstring val2 = sw3.get();
214             swap(sw2, sw3);
215             TEST(sw2.get() == val2);
216             TEST(sw3.get() == heapVal);
217         }
218         {
219             stackstring sw2(stack), sw3(stack);
220             sw3.get()[0] = 'z';
221             const std::wstring val2 = sw3.get();
222             swap(sw2, sw3);
223             TEST(sw2.get() == val2);
224             TEST(sw3.get() == stackVal);
225         }
226         std::cout << "-- Sanity check" << std::endl;
227         TEST(stack.get() == stackVal);
228         TEST(heap.get() == heapVal);
229     }
230     {
231         std::cout << "-- Test putting stackstrings into vector (done by args) class" << std::endl;
232         // Use a smallish buffer, to have stack and heap values
233         typedef boost::nowide::basic_stackstring<wchar_t, char, 5> stackstring;
234         std::vector<stackstring> strings;
235         strings.resize(2);
236         TEST(strings[0].convert("1234") == std::wstring(L"1234"));
237         TEST(strings[1].convert("Hello World") == std::wstring(L"Hello World"));
238         strings.push_back(stackstring("FooBar"));
239         TEST(strings[0].get() == std::wstring(L"1234"));
240         TEST(strings[1].get() == std::wstring(L"Hello World"));
241         TEST(strings[2].get() == std::wstring(L"FooBar"));
242     }
243     std::cout << "- Stackstring" << std::endl;
244     run_all(stackstring_to_wide, stackstring_to_narrow);
245     std::cout << "- Heap Stackstring" << std::endl;
246     run_all(heap_stackstring_to_wide, heap_stackstring_to_narrow);
247 }
248