fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / rapidjson-1.1.0 / test / unittest / simdtest.cpp
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 // 
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed 
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
13 // specific language governing permissions and limitations under the License.
14
15 // Since Travis CI installs old Valgrind 3.7.0, which fails with some SSE4.2
16 // The unit tests prefix with SIMD should be skipped by Valgrind test
17
18 // __SSE2__ and __SSE4_2__ are recognized by gcc, clang, and the Intel compiler.
19 // We use -march=native with gmake to enable -msse2 and -msse4.2, if supported.
20 #if defined(__SSE4_2__)
21 #  define RAPIDJSON_SSE42
22 #elif defined(__SSE2__)
23 #  define RAPIDJSON_SSE2
24 #endif
25
26 #define RAPIDJSON_NAMESPACE rapidjson_simd
27
28 #include "unittest.h"
29
30 #include "rapidjson/reader.h"
31 #include "rapidjson/writer.h"
32
33 #ifdef __GNUC__
34 RAPIDJSON_DIAG_PUSH
35 RAPIDJSON_DIAG_OFF(effc++)
36 #endif
37
38 using namespace rapidjson_simd;
39
40 #ifdef RAPIDJSON_SSE2
41 #define SIMD_SUFFIX(name) name##_SSE2
42 #elif defined(RAPIDJSON_SSE42)
43 #define SIMD_SUFFIX(name) name##_SSE42
44 #else
45 #define SIMD_SUFFIX(name) name
46 #endif
47
48 template <typename StreamType>
49 void TestSkipWhitespace() {
50     for (size_t step = 1; step < 32; step++) {
51         char buffer[1025];
52         for (size_t i = 0; i < 1024; i++)
53             buffer[i] = " \t\r\n"[i % 4];
54         for (size_t i = 0; i < 1024; i += step)
55             buffer[i] = 'X';
56         buffer[1024] = '\0';
57
58         StreamType s(buffer);
59         size_t i = 0;
60         for (;;) {
61             SkipWhitespace(s);
62             if (s.Peek() == '\0')
63                 break;
64             EXPECT_EQ(i, s.Tell());
65             EXPECT_EQ('X', s.Take());
66             i += step;
67         }
68     }
69 }
70
71 TEST(SIMD, SIMD_SUFFIX(SkipWhitespace)) {
72     TestSkipWhitespace<StringStream>();
73     TestSkipWhitespace<InsituStringStream>();
74 }
75
76 TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
77     for (size_t step = 1; step < 32; step++) {
78         char buffer[1024];
79         for (size_t i = 0; i < 1024; i++)
80             buffer[i] = " \t\r\n"[i % 4];
81         for (size_t i = 0; i < 1024; i += step)
82             buffer[i] = 'X';
83
84         MemoryStream ms(buffer, 1024);
85         EncodedInputStream<UTF8<>, MemoryStream> s(ms);
86         size_t i = 0;
87         for (;;) {
88             SkipWhitespace(s);
89             if (s.Peek() == '\0')
90                 break;
91             //EXPECT_EQ(i, s.Tell());
92             EXPECT_EQ('X', s.Take());
93             i += step;
94         }
95     }
96 }
97
98 struct ScanCopyUnescapedStringHandler : BaseReaderHandler<UTF8<>, ScanCopyUnescapedStringHandler> {
99     bool String(const char* str, size_t length, bool) {
100         memcpy(buffer, str, length + 1);
101         return true;
102     }
103     char buffer[1024 + 5 + 32];
104 };
105
106 template <unsigned parseFlags, typename StreamType>
107 void TestScanCopyUnescapedString() {
108     char buffer[1024 + 5 + 32];
109     char backup[1024 + 5 + 32];
110
111     // Test "ABCDABCD...\\"
112     for (size_t offset = 0; offset < 32; offset++) {
113         for (size_t step = 0; step < 1024; step++) {
114             char* json = buffer + offset;
115             char *p = json;
116             *p++ = '\"';
117             for (size_t i = 0; i < step; i++)
118                 *p++ = "ABCD"[i % 4];
119             *p++ = '\\';
120             *p++ = '\\';
121             *p++ = '\"';
122             *p++ = '\0';
123             strcpy(backup, json); // insitu parsing will overwrite buffer, so need to backup first
124
125             StreamType s(json);
126             Reader reader;
127             ScanCopyUnescapedStringHandler h;
128             reader.Parse<parseFlags>(s, h);
129             EXPECT_TRUE(memcmp(h.buffer, backup + 1, step) == 0);
130             EXPECT_EQ('\\', h.buffer[step]);    // escaped
131             EXPECT_EQ('\0', h.buffer[step + 1]);
132         }
133     }
134
135     // Test "\\ABCDABCD..."
136     for (size_t offset = 0; offset < 32; offset++) {
137         for (size_t step = 0; step < 1024; step++) {
138             char* json = buffer + offset;
139             char *p = json;
140             *p++ = '\"';
141             *p++ = '\\';
142             *p++ = '\\';
143             for (size_t i = 0; i < step; i++)
144                 *p++ = "ABCD"[i % 4];
145             *p++ = '\"';
146             *p++ = '\0';
147             strcpy(backup, json); // insitu parsing will overwrite buffer, so need to backup first
148
149             StreamType s(json);
150             Reader reader;
151             ScanCopyUnescapedStringHandler h;
152             reader.Parse<parseFlags>(s, h);
153             EXPECT_TRUE(memcmp(h.buffer + 1, backup + 3, step) == 0);
154             EXPECT_EQ('\\', h.buffer[0]);    // escaped
155             EXPECT_EQ('\0', h.buffer[step + 1]);
156         }
157     }
158 }
159
160 TEST(SIMD, SIMD_SUFFIX(ScanCopyUnescapedString)) {
161     TestScanCopyUnescapedString<kParseDefaultFlags, StringStream>();
162     TestScanCopyUnescapedString<kParseInsituFlag, InsituStringStream>();
163 }
164
165 TEST(SIMD, SIMD_SUFFIX(ScanWriteUnescapedString)) {
166     char buffer[2048 + 1 + 32];
167     for (size_t offset = 0; offset < 32; offset++) {
168         for (size_t step = 0; step < 1024; step++) {
169             char* s = buffer + offset;
170             char* p = s;
171             for (size_t i = 0; i < step; i++)
172                 *p++ = "ABCD"[i % 4];
173             char escape = "\0\n\\\""[step % 4];
174             *p++ = escape;
175             for (size_t i = 0; i < step; i++)
176                 *p++ = "ABCD"[i % 4];
177
178             StringBuffer sb;
179             Writer<StringBuffer> writer(sb);
180             writer.String(s, SizeType(step * 2 + 1));
181             const char* q = sb.GetString();
182             EXPECT_EQ('\"', *q++);
183             for (size_t i = 0; i < step; i++)
184                 EXPECT_EQ("ABCD"[i % 4], *q++);
185             if (escape == '\0') {
186                 EXPECT_EQ('\\', *q++);
187                 EXPECT_EQ('u', *q++);
188                 EXPECT_EQ('0', *q++);
189                 EXPECT_EQ('0', *q++);
190                 EXPECT_EQ('0', *q++);
191                 EXPECT_EQ('0', *q++);
192             }
193             else if (escape == '\n') {
194                 EXPECT_EQ('\\', *q++);
195                 EXPECT_EQ('n', *q++);
196             }
197             else if (escape == '\\') {
198                 EXPECT_EQ('\\', *q++);
199                 EXPECT_EQ('\\', *q++);
200             }
201             else if (escape == '\"') {
202                 EXPECT_EQ('\\', *q++);
203                 EXPECT_EQ('\"', *q++);
204             }
205             for (size_t i = 0; i < step; i++)
206                 EXPECT_EQ("ABCD"[i % 4], *q++);
207             EXPECT_EQ('\"', *q++);
208             EXPECT_EQ('\0', *q++);
209         }
210     }
211 }
212
213 #ifdef __GNUC__
214 RAPIDJSON_DIAG_POP
215 #endif