fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / rapidjson-1.1.0 / include / rapidjson / writer.h
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 #ifndef RAPIDJSON_WRITER_H_
16 #define RAPIDJSON_WRITER_H_
17
18 #include "stream.h"
19 #include "internal/stack.h"
20 #include "internal/strfunc.h"
21 #include "internal/dtoa.h"
22 #include "internal/itoa.h"
23 #include "stringbuffer.h"
24 #include <new>      // placement new
25
26 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
27 #include <intrin.h>
28 #pragma intrinsic(_BitScanForward)
29 #endif
30 #ifdef RAPIDJSON_SSE42
31 #include <nmmintrin.h>
32 #elif defined(RAPIDJSON_SSE2)
33 #include <emmintrin.h>
34 #endif
35
36 #ifdef _MSC_VER
37 RAPIDJSON_DIAG_PUSH
38 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
39 #endif
40
41 #ifdef __clang__
42 RAPIDJSON_DIAG_PUSH
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(unreachable-code)
45 #endif
46
47 RAPIDJSON_NAMESPACE_BEGIN
48
49 ///////////////////////////////////////////////////////////////////////////////
50 // WriteFlag
51
52 /*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS 
53     \ingroup RAPIDJSON_CONFIG
54     \brief User-defined kWriteDefaultFlags definition.
55
56     User can define this as any \c WriteFlag combinations.
57 */
58 #ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
59 #define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
60 #endif
61
62 //! Combination of writeFlags
63 enum WriteFlag {
64     kWriteNoFlags = 0,              //!< No flags are set.
65     kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
66     kWriteNanAndInfFlag = 2,        //!< Allow writing of Infinity, -Infinity and NaN.
67     kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS  //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
68 };
69
70 //! JSON writer
71 /*! Writer implements the concept Handler.
72     It generates JSON text by events to an output os.
73
74     User may programmatically calls the functions of a writer to generate JSON text.
75
76     On the other side, a writer can also be passed to objects that generates events, 
77
78     for example Reader::Parse() and Document::Accept().
79
80     \tparam OutputStream Type of output stream.
81     \tparam SourceEncoding Encoding of source string.
82     \tparam TargetEncoding Encoding of output stream.
83     \tparam StackAllocator Type of allocator for allocating memory of stack.
84     \note implements Handler concept
85 */
86 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
87 class Writer {
88 public:
89     typedef typename SourceEncoding::Ch Ch;
90
91     static const int kDefaultMaxDecimalPlaces = 324;
92
93     //! Constructor
94     /*! \param os Output stream.
95         \param stackAllocator User supplied allocator. If it is null, it will create a private one.
96         \param levelDepth Initial capacity of stack.
97     */
98     explicit
99     Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : 
100         os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
101
102     explicit
103     Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
104         os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
105
106     //! Reset the writer with a new stream.
107     /*!
108         This function reset the writer with a new stream and default settings,
109         in order to make a Writer object reusable for output multiple JSONs.
110
111         \param os New output stream.
112         \code
113         Writer<OutputStream> writer(os1);
114         writer.StartObject();
115         // ...
116         writer.EndObject();
117
118         writer.Reset(os2);
119         writer.StartObject();
120         // ...
121         writer.EndObject();
122         \endcode
123     */
124     void Reset(OutputStream& os) {
125         os_ = &os;
126         hasRoot_ = false;
127         level_stack_.Clear();
128     }
129
130     //! Checks whether the output is a complete JSON.
131     /*!
132         A complete JSON has a complete root object or array.
133     */
134     bool IsComplete() const {
135         return hasRoot_ && level_stack_.Empty();
136     }
137
138     int GetMaxDecimalPlaces() const {
139         return maxDecimalPlaces_;
140     }
141
142     //! Sets the maximum number of decimal places for double output.
143     /*!
144         This setting truncates the output with specified number of decimal places.
145
146         For example, 
147
148         \code
149         writer.SetMaxDecimalPlaces(3);
150         writer.StartArray();
151         writer.Double(0.12345);                 // "0.123"
152         writer.Double(0.0001);                  // "0.0"
153         writer.Double(1.234567890123456e30);    // "1.234567890123456e30" (do not truncate significand for positive exponent)
154         writer.Double(1.23e-4);                 // "0.0"                  (do truncate significand for negative exponent)
155         writer.EndArray();
156         \endcode
157
158         The default setting does not truncate any decimal places. You can restore to this setting by calling
159         \code
160         writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);
161         \endcode
162     */
163     void SetMaxDecimalPlaces(int maxDecimalPlaces) {
164         maxDecimalPlaces_ = maxDecimalPlaces;
165     }
166
167     /*!@name Implementation of Handler
168         \see Handler
169     */
170     //@{
171
172     bool Null()                 { Prefix(kNullType);   return EndValue(WriteNull()); }
173     bool Bool(bool b)           { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }
174     bool Int(int i)             { Prefix(kNumberType); return EndValue(WriteInt(i)); }
175     bool Uint(unsigned u)       { Prefix(kNumberType); return EndValue(WriteUint(u)); }
176     bool Int64(int64_t i64)     { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }
177     bool Uint64(uint64_t u64)   { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }
178
179     //! Writes the given \c double value to the stream
180     /*!
181         \param d The value to be written.
182         \return Whether it is succeed.
183     */
184     bool Double(double d)       { Prefix(kNumberType); return EndValue(WriteDouble(d)); }
185
186     bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
187         (void)copy;
188         Prefix(kNumberType);
189         return EndValue(WriteString(str, length));
190     }
191
192     bool String(const Ch* str, SizeType length, bool copy = false) {
193         (void)copy;
194         Prefix(kStringType);
195         return EndValue(WriteString(str, length));
196     }
197
198 #if RAPIDJSON_HAS_STDSTRING
199     bool String(const std::basic_string<Ch>& str) {
200         return String(str.data(), SizeType(str.size()));
201     }
202 #endif
203
204     bool StartObject() {
205         Prefix(kObjectType);
206         new (level_stack_.template Push<Level>()) Level(false);
207         return WriteStartObject();
208     }
209
210     bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
211
212     bool EndObject(SizeType memberCount = 0) {
213         (void)memberCount;
214         RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
215         RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
216         level_stack_.template Pop<Level>(1);
217         return EndValue(WriteEndObject());
218     }
219
220     bool StartArray() {
221         Prefix(kArrayType);
222         new (level_stack_.template Push<Level>()) Level(true);
223         return WriteStartArray();
224     }
225
226     bool EndArray(SizeType elementCount = 0) {
227         (void)elementCount;
228         RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
229         RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
230         level_stack_.template Pop<Level>(1);
231         return EndValue(WriteEndArray());
232     }
233     //@}
234
235     /*! @name Convenience extensions */
236     //@{
237
238     //! Simpler but slower overload.
239     bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
240     bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
241
242     //@}
243
244     //! Write a raw JSON value.
245     /*!
246         For user to write a stringified JSON as a value.
247
248         \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
249         \param length Length of the json.
250         \param type Type of the root of json.
251     */
252     bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return EndValue(WriteRawValue(json, length)); }
253
254 protected:
255     //! Information for each nested level
256     struct Level {
257         Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
258         size_t valueCount;  //!< number of values in this level
259         bool inArray;       //!< true if in array, otherwise in object
260     };
261
262     static const size_t kDefaultLevelDepth = 32;
263
264     bool WriteNull()  {
265         PutReserve(*os_, 4);
266         PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
267     }
268
269     bool WriteBool(bool b)  {
270         if (b) {
271             PutReserve(*os_, 4);
272             PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
273         }
274         else {
275             PutReserve(*os_, 5);
276             PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
277         }
278         return true;
279     }
280
281     bool WriteInt(int i) {
282         char buffer[11];
283         const char* end = internal::i32toa(i, buffer);
284         PutReserve(*os_, static_cast<size_t>(end - buffer));
285         for (const char* p = buffer; p != end; ++p)
286             PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
287         return true;
288     }
289
290     bool WriteUint(unsigned u) {
291         char buffer[10];
292         const char* end = internal::u32toa(u, buffer);
293         PutReserve(*os_, static_cast<size_t>(end - buffer));
294         for (const char* p = buffer; p != end; ++p)
295             PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
296         return true;
297     }
298
299     bool WriteInt64(int64_t i64) {
300         char buffer[21];
301         const char* end = internal::i64toa(i64, buffer);
302         PutReserve(*os_, static_cast<size_t>(end - buffer));
303         for (const char* p = buffer; p != end; ++p)
304             PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
305         return true;
306     }
307
308     bool WriteUint64(uint64_t u64) {
309         char buffer[20];
310         char* end = internal::u64toa(u64, buffer);
311         PutReserve(*os_, static_cast<size_t>(end - buffer));
312         for (char* p = buffer; p != end; ++p)
313             PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
314         return true;
315     }
316
317     bool WriteDouble(double d) {
318         if (internal::Double(d).IsNanOrInf()) {
319             if (!(writeFlags & kWriteNanAndInfFlag))
320                 return false;
321             if (internal::Double(d).IsNan()) {
322                 PutReserve(*os_, 3);
323                 PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
324                 return true;
325             }
326             if (internal::Double(d).Sign()) {
327                 PutReserve(*os_, 9);
328                 PutUnsafe(*os_, '-');
329             }
330             else
331                 PutReserve(*os_, 8);
332             PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
333             PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
334             return true;
335         }
336
337         char buffer[25];
338         char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
339         PutReserve(*os_, static_cast<size_t>(end - buffer));
340         for (char* p = buffer; p != end; ++p)
341             PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
342         return true;
343     }
344
345     bool WriteString(const Ch* str, SizeType length)  {
346         static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
347         static const char escape[256] = {
348 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
349             //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
350             'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
351             'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
352               0,   0, '"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20
353             Z16, Z16,                                                                       // 30~4F
354               0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\',   0,   0,   0, // 50
355             Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16                                // 60~FF
356 #undef Z16
357         };
358
359         if (TargetEncoding::supportUnicode)
360             PutReserve(*os_, 2 + length * 6); // "\uxxxx..."
361         else
362             PutReserve(*os_, 2 + length * 12);  // "\uxxxx\uyyyy..."
363
364         PutUnsafe(*os_, '\"');
365         GenericStringStream<SourceEncoding> is(str);
366         while (ScanWriteUnescapedString(is, length)) {
367             const Ch c = is.Peek();
368             if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
369                 // Unicode escaping
370                 unsigned codepoint;
371                 if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))
372                     return false;
373                 PutUnsafe(*os_, '\\');
374                 PutUnsafe(*os_, 'u');
375                 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
376                     PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
377                     PutUnsafe(*os_, hexDigits[(codepoint >>  8) & 15]);
378                     PutUnsafe(*os_, hexDigits[(codepoint >>  4) & 15]);
379                     PutUnsafe(*os_, hexDigits[(codepoint      ) & 15]);
380                 }
381                 else {
382                     RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
383                     // Surrogate pair
384                     unsigned s = codepoint - 0x010000;
385                     unsigned lead = (s >> 10) + 0xD800;
386                     unsigned trail = (s & 0x3FF) + 0xDC00;
387                     PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
388                     PutUnsafe(*os_, hexDigits[(lead >>  8) & 15]);
389                     PutUnsafe(*os_, hexDigits[(lead >>  4) & 15]);
390                     PutUnsafe(*os_, hexDigits[(lead      ) & 15]);
391                     PutUnsafe(*os_, '\\');
392                     PutUnsafe(*os_, 'u');
393                     PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
394                     PutUnsafe(*os_, hexDigits[(trail >>  8) & 15]);
395                     PutUnsafe(*os_, hexDigits[(trail >>  4) & 15]);
396                     PutUnsafe(*os_, hexDigits[(trail      ) & 15]);                    
397                 }
398             }
399             else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)]))  {
400                 is.Take();
401                 PutUnsafe(*os_, '\\');
402                 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));
403                 if (escape[static_cast<unsigned char>(c)] == 'u') {
404                     PutUnsafe(*os_, '0');
405                     PutUnsafe(*os_, '0');
406                     PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);
407                     PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
408                 }
409             }
410             else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? 
411                 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
412                 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
413                 return false;
414         }
415         PutUnsafe(*os_, '\"');
416         return true;
417     }
418
419     bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {
420         return RAPIDJSON_LIKELY(is.Tell() < length);
421     }
422
423     bool WriteStartObject() { os_->Put('{'); return true; }
424     bool WriteEndObject()   { os_->Put('}'); return true; }
425     bool WriteStartArray()  { os_->Put('['); return true; }
426     bool WriteEndArray()    { os_->Put(']'); return true; }
427
428     bool WriteRawValue(const Ch* json, size_t length) {
429         PutReserve(*os_, length);
430         for (size_t i = 0; i < length; i++) {
431             RAPIDJSON_ASSERT(json[i] != '\0');
432             PutUnsafe(*os_, json[i]);
433         }
434         return true;
435     }
436
437     void Prefix(Type type) {
438         (void)type;
439         if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
440             Level* level = level_stack_.template Top<Level>();
441             if (level->valueCount > 0) {
442                 if (level->inArray) 
443                     os_->Put(','); // add comma if it is not the first element in array
444                 else  // in object
445                     os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
446             }
447             if (!level->inArray && level->valueCount % 2 == 0)
448                 RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name
449             level->valueCount++;
450         }
451         else {
452             RAPIDJSON_ASSERT(!hasRoot_);    // Should only has one and only one root.
453             hasRoot_ = true;
454         }
455     }
456
457     // Flush the value if it is the top level one.
458     bool EndValue(bool ret) {
459         if (RAPIDJSON_UNLIKELY(level_stack_.Empty()))   // end of json text
460             os_->Flush();
461         return ret;
462     }
463
464     OutputStream* os_;
465     internal::Stack<StackAllocator> level_stack_;
466     int maxDecimalPlaces_;
467     bool hasRoot_;
468
469 private:
470     // Prohibit copy constructor & assignment operator.
471     Writer(const Writer&);
472     Writer& operator=(const Writer&);
473 };
474
475 // Full specialization for StringStream to prevent memory copying
476
477 template<>
478 inline bool Writer<StringBuffer>::WriteInt(int i) {
479     char *buffer = os_->Push(11);
480     const char* end = internal::i32toa(i, buffer);
481     os_->Pop(static_cast<size_t>(11 - (end - buffer)));
482     return true;
483 }
484
485 template<>
486 inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
487     char *buffer = os_->Push(10);
488     const char* end = internal::u32toa(u, buffer);
489     os_->Pop(static_cast<size_t>(10 - (end - buffer)));
490     return true;
491 }
492
493 template<>
494 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
495     char *buffer = os_->Push(21);
496     const char* end = internal::i64toa(i64, buffer);
497     os_->Pop(static_cast<size_t>(21 - (end - buffer)));
498     return true;
499 }
500
501 template<>
502 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
503     char *buffer = os_->Push(20);
504     const char* end = internal::u64toa(u, buffer);
505     os_->Pop(static_cast<size_t>(20 - (end - buffer)));
506     return true;
507 }
508
509 template<>
510 inline bool Writer<StringBuffer>::WriteDouble(double d) {
511     if (internal::Double(d).IsNanOrInf()) {
512         // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
513         if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
514             return false;
515         if (internal::Double(d).IsNan()) {
516             PutReserve(*os_, 3);
517             PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
518             return true;
519         }
520         if (internal::Double(d).Sign()) {
521             PutReserve(*os_, 9);
522             PutUnsafe(*os_, '-');
523         }
524         else
525             PutReserve(*os_, 8);
526         PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
527         PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
528         return true;
529     }
530     
531     char *buffer = os_->Push(25);
532     char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
533     os_->Pop(static_cast<size_t>(25 - (end - buffer)));
534     return true;
535 }
536
537 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
538 template<>
539 inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
540     if (length < 16)
541         return RAPIDJSON_LIKELY(is.Tell() < length);
542
543     if (!RAPIDJSON_LIKELY(is.Tell() < length))
544         return false;
545
546     const char* p = is.src_;
547     const char* end = is.head_ + length;
548     const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
549     const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
550     if (nextAligned > end)
551         return true;
552
553     while (p != nextAligned)
554         if (*p < 0x20 || *p == '\"' || *p == '\\') {
555             is.src_ = p;
556             return RAPIDJSON_LIKELY(is.Tell() < length);
557         }
558         else
559             os_->PutUnsafe(*p++);
560
561     // The rest of string using SIMD
562     static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
563     static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
564     static const char space[16]  = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
565     const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
566     const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
567     const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
568
569     for (; p != endAligned; p += 16) {
570         const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
571         const __m128i t1 = _mm_cmpeq_epi8(s, dq);
572         const __m128i t2 = _mm_cmpeq_epi8(s, bs);
573         const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
574         const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
575         unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
576         if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped
577             SizeType len;
578 #ifdef _MSC_VER         // Find the index of first escaped
579             unsigned long offset;
580             _BitScanForward(&offset, r);
581             len = offset;
582 #else
583             len = static_cast<SizeType>(__builtin_ffs(r) - 1);
584 #endif
585             char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
586             for (size_t i = 0; i < len; i++)
587                 q[i] = p[i];
588
589             p += len;
590             break;
591         }
592         _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);
593     }
594
595     is.src_ = p;
596     return RAPIDJSON_LIKELY(is.Tell() < length);
597 }
598 #endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
599
600 RAPIDJSON_NAMESPACE_END
601
602 #ifdef _MSC_VER
603 RAPIDJSON_DIAG_POP
604 #endif
605
606 #ifdef __clang__
607 RAPIDJSON_DIAG_POP
608 #endif
609
610 #endif // RAPIDJSON_RAPIDJSON_H_