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 {
87 WTF_MAKE_FAST_ALLOCATED;
88public:
89 static FormattedNumber fixedPrecision(double number, unsigned significantFigures = 6, TrailingZerosTruncatingPolicy trailingZerosTruncatingPolicy = TruncateTrailingZeros)
90 {
91 FormattedNumber numberFormatter;
92 numberToFixedPrecisionString(number, significantFigures, numberFormatter.m_buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros);
93 numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
94 return numberFormatter;
95 }
96
97 static FormattedNumber fixedWidth(double number, unsigned decimalPlaces)
98 {
99 FormattedNumber numberFormatter;
100 numberToFixedWidthString(number, decimalPlaces, numberFormatter.m_buffer);
101 numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
102 return numberFormatter;
103 }
104
105 unsigned length() const { return m_length; }
106 const LChar* buffer() const { return reinterpret_cast<const LChar*>(&m_buffer[0]); }
107
108private:
109 NumberToStringBuffer m_buffer;
110 unsigned m_length;
111};
112
113template<> class StringTypeAdapter<FormattedNumber> {
114public:
115 StringTypeAdapter(const FormattedNumber& number)
116 : m_number { number }
117 {
118 }
119
120 unsigned length() const { return m_number.length(); }
121 bool is8Bit() const { return true; }
122 template<typename CharacterType> void writeTo(CharacterType* destination) const { StringImpl::copyCharacters(destination, m_number.buffer(), m_number.length()); }
123
124private:
125 const FormattedNumber& m_number;
126};
127
128}
129
130using WTF::FormattedNumber;
131