123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- // Tencent is pleased to support the open source community by making RapidJSON available.
- //
- // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
- //
- // Licensed under the MIT License (the "License"); you may not use this file except
- // in compliance with the License. You may obtain a copy of the License at
- //
- // http://opensource.org/licenses/MIT
- //
- // Unless required by applicable law or agreed to in writing, software distributed
- // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- // CONDITIONS OF ANY KIND, either express or implied. See the License for the
- // specific language governing permissions and limitations under the License.
- #include "unittest.h"
- #include "rapidjson/internal/itoa.h"
- #ifdef __GNUC__
- RAPIDJSON_DIAG_PUSH
- RAPIDJSON_DIAG_OFF(type-limits)
- #endif
- using namespace rapidjson::internal;
- template <typename T>
- struct Traits {
- };
- template <>
- struct Traits<uint32_t> {
- enum { kBufferSize = 11 };
- enum { kMaxDigit = 10 };
- static uint32_t Negate(uint32_t x) { return x; }
- };
- template <>
- struct Traits<int32_t> {
- enum { kBufferSize = 12 };
- enum { kMaxDigit = 10 };
- static int32_t Negate(int32_t x) { return -x; }
- };
- template <>
- struct Traits<uint64_t> {
- enum { kBufferSize = 21 };
- enum { kMaxDigit = 20 };
- static uint64_t Negate(uint64_t x) { return x; }
- };
- template <>
- struct Traits<int64_t> {
- enum { kBufferSize = 22 };
- enum { kMaxDigit = 20 };
- static int64_t Negate(int64_t x) { return -x; }
- };
- template <typename T>
- static void VerifyValue(T value, void(*f)(T, char*), char* (*g)(T, char*)) {
- char buffer1[Traits<T>::kBufferSize];
- char buffer2[Traits<T>::kBufferSize];
- f(value, buffer1);
- *g(value, buffer2) = '\0';
-
- EXPECT_STREQ(buffer1, buffer2);
- }
- template <typename T>
- static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) {
- // Boundary cases
- VerifyValue<T>(0, f, g);
- VerifyValue<T>(std::numeric_limits<T>::min(), f, g);
- VerifyValue<T>(std::numeric_limits<T>::max(), f, g);
- // 2^n - 1, 2^n, 10^n - 1, 10^n until overflow
- for (int power = 2; power <= 10; power += 8) {
- T i = 1, last;
- do {
- VerifyValue<T>(i - 1, f, g);
- VerifyValue<T>(i, f, g);
- if (std::numeric_limits<T>::min() < 0) {
- VerifyValue<T>(Traits<T>::Negate(i), f, g);
- VerifyValue<T>(Traits<T>::Negate(i + 1), f, g);
- }
- last = i;
- if (i > static_cast<T>(std::numeric_limits<T>::max() / static_cast<T>(power)))
- break;
- i *= static_cast<T>(power);
- } while (last < i);
- }
- }
- static void u32toa_naive(uint32_t value, char* buffer) {
- char temp[10];
- char *p = temp;
- do {
- *p++ = static_cast<char>(char(value % 10) + '0');
- value /= 10;
- } while (value > 0);
- do {
- *buffer++ = *--p;
- } while (p != temp);
- *buffer = '\0';
- }
- static void i32toa_naive(int32_t value, char* buffer) {
- uint32_t u = static_cast<uint32_t>(value);
- if (value < 0) {
- *buffer++ = '-';
- u = ~u + 1;
- }
- u32toa_naive(u, buffer);
- }
- static void u64toa_naive(uint64_t value, char* buffer) {
- char temp[20];
- char *p = temp;
- do {
- *p++ = static_cast<char>(char(value % 10) + '0');
- value /= 10;
- } while (value > 0);
- do {
- *buffer++ = *--p;
- } while (p != temp);
- *buffer = '\0';
- }
- static void i64toa_naive(int64_t value, char* buffer) {
- uint64_t u = static_cast<uint64_t>(value);
- if (value < 0) {
- *buffer++ = '-';
- u = ~u + 1;
- }
- u64toa_naive(u, buffer);
- }
- TEST(itoa, u32toa) {
- Verify(u32toa_naive, u32toa);
- }
- TEST(itoa, i32toa) {
- Verify(i32toa_naive, i32toa);
- }
- TEST(itoa, u64toa) {
- Verify(u64toa_naive, u64toa);
- }
- TEST(itoa, i64toa) {
- Verify(i64toa_naive, i64toa);
- }
- #ifdef __GNUC__
- RAPIDJSON_DIAG_POP
- #endif
|