File: test_stackstring.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (245 lines) | stat: -rw-r--r-- 8,632 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
//
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
// Copyright (c) 2019-2020 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/nowide/stackstring.hpp>
#include "test.hpp"
#include "test_sets.hpp"
#include <iostream>
#include <vector>

#if defined(BOOST_MSVC) && BOOST_MSVC < 1700
#pragma warning(disable : 4428) // universal-character-name encountered in source
#endif

template<typename CharOut, typename CharIn, size_t BufferSize>
class test_basic_stackstring : public boost::nowide::basic_stackstring<CharOut, CharIn, BufferSize>
{
public:
    using parent = boost::nowide::basic_stackstring<CharOut, CharIn, BufferSize>;

    using parent::parent;
    using parent::uses_stack_memory;
    bool uses_heap_memory() const
    {
        return !uses_stack_memory() && this->get();
    }
};

using test_wstackstring = test_basic_stackstring<wchar_t, char, 256>;
using test_stackstring = test_basic_stackstring<char, wchar_t, 256>;

std::wstring stackstring_to_wide(const std::string& s)
{
    const test_wstackstring ss(s.c_str());
    TEST(ss.uses_stack_memory());
    return ss.get();
}

std::string stackstring_to_narrow(const std::wstring& s)
{
    const test_stackstring ss(s.c_str());
    TEST(ss.uses_stack_memory());
    return ss.get();
}

std::wstring heap_stackstring_to_wide(const std::string& s)
{
    const test_basic_stackstring<wchar_t, char, 1> ss(s.c_str());
    TEST(ss.uses_heap_memory() || s.empty());
    return ss.get();
}

std::string heap_stackstring_to_narrow(const std::wstring& s)
{
    const test_basic_stackstring<char, wchar_t, 1> ss(s.c_str());
    TEST(ss.uses_heap_memory() || s.empty());
    return ss.get();
}

// coverity[root_function]
void test_main(int, char**, char**)
{
    std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
    std::wstring whello = boost::nowide::widen(hello);
    const wchar_t* wempty = L"";

    {
        std::cout << "-- Default constructed string is NULL" << std::endl;
        const boost::nowide::short_stackstring s;
        TEST(s.get() == nullptr);
    }
    {
        std::cout << "-- nullptr passed to ctor results in NULL" << std::endl;
        const boost::nowide::short_stackstring s(nullptr);
        TEST(s.get() == nullptr);
        const boost::nowide::short_stackstring s2(nullptr, nullptr);
        TEST(s2.get() == nullptr);
    }
    {
        std::cout << "-- nullptr passed to convert results in NULL" << std::endl;
        boost::nowide::short_stackstring s(L"foo");
        TEST(s.get() == std::string("foo"));
        s.convert(nullptr);
        TEST(s.get() == nullptr);
        boost::nowide::short_stackstring s2(L"foo");
        TEST(s2.get() == std::string("foo"));
        s2.convert(nullptr, nullptr);
        TEST(s2.get() == nullptr);
    }
    {
        std::cout << "-- An empty string is accepted" << std::endl;
        const boost::nowide::short_stackstring s(wempty);
        TEST(s.get());
        TEST(s.get() == std::string());
        const boost::nowide::short_stackstring s2(wempty, wempty);
        TEST(s2.get());
        TEST(s2.get() == std::string());
    }
    {
        std::cout << "-- An empty string is accepted" << std::endl;
        boost::nowide::short_stackstring s, s2;
        TEST(s.convert(wempty));
        TEST(s.get() == std::string());
        TEST(s2.convert(wempty, wempty));
        TEST(s2.get() == std::string());
    }
    {
        std::cout << "-- Will be put on heap" << std::endl;
        test_basic_stackstring<wchar_t, char, 3> sw;
        TEST(sw.convert(hello.c_str()));
        TEST(sw.uses_heap_memory());
        TEST(sw.get() == whello);
        TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
        TEST(sw.uses_heap_memory());
        TEST(sw.get() == whello);
    }
    {
        std::cout << "-- Will be put on stack" << std::endl;
        test_basic_stackstring<wchar_t, char, 40> sw;
        TEST(sw.convert(hello.c_str()));
        TEST(sw.uses_stack_memory());
        TEST(sw.get() == whello);
        TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
        TEST(sw.uses_stack_memory());
        TEST(sw.get() == whello);
    }
    {
        std::cout << "-- Will be put on heap" << std::endl;
        test_basic_stackstring<char, wchar_t, 3> sw;
        TEST(sw.convert(whello.c_str()));
        TEST(sw.uses_heap_memory());
        TEST(sw.get() == hello);
        TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
        TEST(sw.uses_heap_memory());
        TEST(sw.get() == hello);
    }
    {
        std::cout << "-- Will be put on stack" << std::endl;
        test_basic_stackstring<char, wchar_t, 40> sw;
        TEST(sw.convert(whello.c_str()));
        TEST(sw.uses_stack_memory());
        TEST(sw.get() == hello);
        TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
        TEST(sw.uses_stack_memory());
        TEST(sw.get() == hello);
    }
    {
        using stackstring = test_basic_stackstring<wchar_t, char, 6>;
        const std::wstring heapVal = L"heapValue";
        const std::wstring stackVal = L"stack";
        const stackstring heap(boost::nowide::narrow(heapVal).c_str());
        const stackstring stack(boost::nowide::narrow(stackVal).c_str());
        TEST(heap.uses_heap_memory());
        TEST(stack.uses_stack_memory());

        {
            stackstring sw2(heap), sw3, sEmpty;
            sw3 = heap;
            TEST(sw2.get() == heapVal);
            TEST(sw3.get() == heapVal);
            // Self assign avoiding clang self-assign-overloaded warning
            sw3 = static_cast<const stackstring&>(sw3); //-V570
            TEST(sw3.get() == heapVal);
            // Assign empty
            sw3 = sEmpty; //-V820
            TEST(sw3.get() == nullptr);
        }
        {
            stackstring sw2(stack), sw3, sEmpty;
            sw3 = stack;
            TEST(sw2.get() == stackVal);
            TEST(sw3.get() == stackVal);
            // Self assign avoiding clang self-assign-overloaded warning
            sw3 = static_cast<const stackstring&>(sw3); //-V570
            TEST(sw3.get() == stackVal);
            // Assign empty
            sw3 = sEmpty; //-V820
            TEST(sw3.get() == nullptr);
        }
        {
            stackstring sw2(stack);
            sw2 = heap;
            TEST(sw2.get() == heapVal);
        }
        {
            stackstring sw2(heap);
            sw2 = stack;
            TEST(sw2.get() == stackVal);
        }
        {
            stackstring sw2(heap), sw3(stack), sEmpty1, sEmpty2;
            swap(sw2, sw3);
            TEST(sw2.get() == stackVal);
            TEST(sw3.get() == heapVal);
            swap(sw2, sw3);
            TEST(sw2.get() == heapVal);
            TEST(sw3.get() == stackVal);
            swap(sw2, sEmpty1);
            TEST(sEmpty1.get() == heapVal);
            TEST(sw2.get() == nullptr);
            swap(sw3, sEmpty2);
            TEST(sEmpty2.get() == stackVal);
            TEST(sw3.get() == nullptr);
        }
        {
            stackstring sw2(heap), sw3(heap);
            sw3.get()[0] = 'z';
            const std::wstring val2 = sw3.get();
            swap(sw2, sw3);
            TEST(sw2.get() == val2);
            TEST(sw3.get() == heapVal);
        }
        {
            stackstring sw2(stack), sw3(stack);
            sw3.get()[0] = 'z';
            const std::wstring val2 = sw3.get();
            swap(sw2, sw3);
            TEST(sw2.get() == val2);
            TEST(sw3.get() == stackVal);
        }
        std::cout << "-- Sanity check" << std::endl;
        TEST(stack.get() == stackVal);
        TEST(heap.get() == heapVal);
    }
    {
        std::cout << "-- Test putting stackstrings into vector (done by args) class" << std::endl;
        // Use a smallish buffer, to have stack and heap values
        using stackstring = boost::nowide::basic_stackstring<wchar_t, char, 5>;
        std::vector<stackstring> strings;
        strings.resize(2);
        TEST(strings[0].convert("1234") == std::wstring(L"1234"));
        TEST(strings[1].convert("Hello World") == std::wstring(L"Hello World"));
        strings.push_back(stackstring("FooBar"));
        TEST(strings[0].get() == std::wstring(L"1234"));
        TEST(strings[1].get() == std::wstring(L"Hello World"));
        TEST(strings[2].get() == std::wstring(L"FooBar"));
    }
    std::cout << "- Stackstring" << std::endl;
    run_all(stackstring_to_wide, stackstring_to_narrow);
    std::cout << "- Heap Stackstring" << std::endl;
    run_all(heap_stackstring_to_wide, heap_stackstring_to_narrow);
}