summaryrefslogtreecommitdiffstats
path: root/contrib/libs/apache/arrow_next/cpp/src/arrow/util/formatting.cc
blob: aeb7d7ff220e470877ed355ac780171c6a486824 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// 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 "contrib/libs/apache/arrow_next/cpp/src/arrow/util/formatting.h"
#include "contrib/libs/apache/arrow_next/src/arrow/util/config.h"
#include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/double_conversion.h"
#include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/float16.h"
#include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/logging.h"

namespace arrow20 {

using util::Float16;
using util::double_conversion::DoubleToStringConverter;

static constexpr int kMinBufferSize = DoubleToStringConverter::kBase10MaximalLength + 1;

namespace internal {
namespace detail {

const char digit_pairs[] =
    "0001020304050607080910111213141516171819"
    "2021222324252627282930313233343536373839"
    "4041424344454647484950515253545556575859"
    "6061626364656667686970717273747576777879"
    "8081828384858687888990919293949596979899";

}  // namespace detail

struct FloatToStringFormatter::Impl {
  Impl()
      : converter_(DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN, "inf", "nan",
                   'e', -6, 10, 6, 0) {}

  Impl(int flags, const char* inf_symbol, const char* nan_symbol, char exp_character,
       int decimal_in_shortest_low, int decimal_in_shortest_high,
       int max_leading_padding_zeroes_in_precision_mode,
       int max_trailing_padding_zeroes_in_precision_mode)
      : converter_(flags, inf_symbol, nan_symbol, exp_character, decimal_in_shortest_low,
                   decimal_in_shortest_high, max_leading_padding_zeroes_in_precision_mode,
                   max_trailing_padding_zeroes_in_precision_mode) {}

  DoubleToStringConverter converter_;
};

FloatToStringFormatter::FloatToStringFormatter() : impl_(new Impl()) {}

FloatToStringFormatter::FloatToStringFormatter(
    int flags, const char* inf_symbol, const char* nan_symbol, char exp_character,
    int decimal_in_shortest_low, int decimal_in_shortest_high,
    int max_leading_padding_zeroes_in_precision_mode,
    int max_trailing_padding_zeroes_in_precision_mode)
    : impl_(new Impl(flags, inf_symbol, nan_symbol, exp_character,
                     decimal_in_shortest_low, decimal_in_shortest_high,
                     max_leading_padding_zeroes_in_precision_mode,
                     max_trailing_padding_zeroes_in_precision_mode)) {}

FloatToStringFormatter::~FloatToStringFormatter() {}

int FloatToStringFormatter::FormatFloat(float v, char* out_buffer, int out_size) {
  DCHECK_GE(out_size, kMinBufferSize);
  // StringBuilder checks bounds in debug mode for us
  util::double_conversion::StringBuilder builder(out_buffer, out_size);
  bool result = impl_->converter_.ToShortestSingle(v, &builder);
  DCHECK(result);
  ARROW_UNUSED(result);
  return builder.position();
}

int FloatToStringFormatter::FormatFloat(double v, char* out_buffer, int out_size) {
  DCHECK_GE(out_size, kMinBufferSize);
  util::double_conversion::StringBuilder builder(out_buffer, out_size);
  bool result = impl_->converter_.ToShortest(v, &builder);
  DCHECK(result);
  ARROW_UNUSED(result);
  return builder.position();
}

int FloatToStringFormatter::FormatFloat(uint16_t v, char* out_buffer, int out_size) {
  DCHECK_GE(out_size, kMinBufferSize);
  util::double_conversion::StringBuilder builder(out_buffer, out_size);
  bool result = impl_->converter_.ToShortest(Float16::FromBits(v).ToFloat(), &builder);
  DCHECK(result);
  ARROW_UNUSED(result);
  return builder.position();
}

}  // namespace internal
}  // namespace arrow20