1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include <wtf/dtoa.h>
29#include <wtf/text/IntegerToStringConversion.h>
30#include <wtf/text/StringConcatenate.h>
31
32namespace WTF {
33
34template<typename SignedInt>
35class StringTypeAdapter<SignedInt, typename std::enable_if_t<std::is_integral<SignedInt>::value && std::is_signed<SignedInt>::value>> {
36public:
37 StringTypeAdapter(SignedInt number)
38 : m_number { number }
39 {
40 }
41
42 unsigned length() const { return lengthOfNumberAsStringSigned(m_number); }
43 bool is8Bit() const { return true; }
44 template<typename CharacterType> void writeTo(CharacterType* destination) const { writeNumberToBufferSigned(m_number, destination); }
45
46private:
47 SignedInt m_number;
48};
49
50template<typename UnsignedInt>
51class StringTypeAdapter<UnsignedInt, typename std::enable_if_t<std::is_integral<UnsignedInt>::value && !std::is_signed<UnsignedInt>::value>> {
52public:
53 StringTypeAdapter(UnsignedInt number)
54 : m_number { number }
55 {
56 }
57
58 unsigned length() const { return lengthOfNumberAsStringUnsigned(m_number); }
59 bool is8Bit() const { return true; }
60 template<typename CharacterType> void writeTo(CharacterType* destination) const { writeNumberToBufferUnsigned(m_number, destination); }
61
62private:
63 UnsignedInt m_number;
64};
65
66template<typename FloatingPoint>
67class StringTypeAdapter<FloatingPoint, typename std::enable_if_t<std::is_floating_point<FloatingPoint>::value>> {
68public:
69 StringTypeAdapter(FloatingPoint number)
70 {
71 numberToString(number, m_buffer);
72 m_length = std::strlen(&m_buffer[0]);
73 }
74
75 unsigned length() const { return m_length; }
76 bool is8Bit() const { return true; }
77 template<typename CharacterType> void writeTo(CharacterType* destination) const { StringImpl::copyCharacters(destination, buffer(), m_length); }
78
79private:
80 const LChar* buffer() const { return reinterpret_cast<const LChar*>(&m_buffer[0]); }
81
82 NumberToStringBuffer m_buffer;
83 unsigned m_length;
84};
85
86class FormattedNumber {
87public:
88 static FormattedNumber fixedPrecision(double number, unsigned significantFigures = 6, TrailingZerosTruncatingPolicy trailingZerosTruncatingPolicy = TruncateTrailingZeros)
89 {
90 FormattedNumber numberFormatter;
91 numberToFixedPrecisionString(number, significantFigures, numberFormatter.m_buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros);
92 numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
93 return numberFormatter;
94 }
95
96 static FormattedNumber fixedWidth(double number, unsigned decimalPlaces)
97 {
98 FormattedNumber numberFormatter;
99 numberToFixedWidthString(number, decimalPlaces, numberFormatter.m_buffer);
100 numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
101 return numberFormatter;
102 }
103
104 unsigned length() const { return m_length; }
105 const LChar* buffer() const { return reinterpret_cast<const LChar*>(&m_buffer[0]); }
106
107private:
108 NumberToStringBuffer m_buffer;
109 unsigned m_length;
110};
111
112template<> class StringTypeAdapter<FormattedNumber> {
113public:
114 StringTypeAdapter(const FormattedNumber& number)
115 : m_number { number }
116 {
117 }
118
119 unsigned length() const { return m_number.length(); }
120 bool is8Bit() const { return true; }
121 template<typename CharacterType> void writeTo(CharacterType* destination) const { StringImpl::copyCharacters(destination, m_number.buffer(), m_number.length()); }
122
123private:
124 const FormattedNumber& m_number;
125};
126
127}
128
129using WTF::FormattedNumber;
130