kblib 0.2.3
General utilities library for modern C++
format.h
Go to the documentation of this file.
1/* *****************************************************************************
2 * kblib is a general utility library for C++14 and C++17, intended to provide
3 * performant high-level abstractions and more expressive ways to do simple
4 * things.
5 *
6 * Copyright (c) 2021 killerbee
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 * ****************************************************************************/
21
32#ifndef KBLIB_FORMAT_H
33#define KBLIB_FORMAT_H
34
35#include "fakestd.h"
36
37#include <algorithm>
38#include <cmath>
39
40namespace KBLIB_NS {
41
49template <typename Number>
50constexpr auto count_digits(Number val)
52 if (val == 0) {
53 return 1;
54 } else {
55 return std::numeric_limits<Number>::digits10;
56 }
57}
58
66template <typename Number>
67constexpr auto count_digits(Number val)
68 -> enable_if_t<not std::is_floating_point<Number>::value
69 and std::is_signed<Number>::value,
70 int> {
71 if (val == 0 or val == 1) {
72 return 1;
73 } else {
74 return static_cast<int>(std::ceil(
75 std::nextafter(std::log10(std::fabs(val)), INFINITY)))
76 + (val < 0);
77 }
78}
79
86template <typename Number>
87constexpr auto count_digits(Number val)
88 -> enable_if_t<std::is_unsigned<Number>::value, int> {
89 if (val == 0) {
90 return 1;
91 } else if (val == static_cast<Number>(-1)) {
92 return static_cast<int>(std::ceil(std::log10(val)));
93 } else {
94 return static_cast<int>(std::ceil(std::log10(val + 1)));
95 }
96}
97
106template <typename Number>
107constexpr auto count_digits(Number val, int base) -> int {
108 if (val == 0) {
109 return 1;
110 } else if (std::is_floating_point<Number>::value) {
111 return static_cast<int>(
112 std::ceil(std::numeric_limits<Number>::digits * std::logb(base)));
113 } else {
114 return static_cast<int>(
115 std::ceil(std::log(std::abs(val) + 1) / std::log(base)))
116 + (val < 0);
117 }
118}
119
129template <typename ForwardIt>
130auto max_count_digits(ForwardIt first, ForwardIt last) -> int {
131 if (first == last) {
132 return 0;
133 }
134 return count_digits(*std::max_element(first, last));
135}
136
147template <typename ForwardIt>
148auto max_count_digits(ForwardIt first, ForwardIt last, int base) -> int {
149 if (first == last) {
150 return 0;
151 }
152 return count_digits(*std::max_element(first, last), base);
153}
154
155} // namespace KBLIB_NS
156
157#endif // KBLIB_FORMAT_H
This header provides some features of C++17 <type_traits> and other headers for C++14,...
typename std::enable_if< B, T >::type enable_if_t
Definition: fakestd.h:54
constexpr auto count_digits(Number val, int base) -> int
Calculates the number of digits needed to represent a number in a given base, plus one for negative n...
Definition: format.h:107
auto max_count_digits(ForwardIt first, ForwardIt last, int base) -> int
Returns the necessary number of digits to represent the largest value in an input range.
Definition: format.h:148
constexpr auto max_element(ForwardIt first, EndIt last, Compare comp={}) -> ForwardIt
Definition: algorithm.h:1109
#define KBLIB_NS
Definition: tdecl.h:113