Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Utility.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_UTIL_UTILITY_HPP
18#define TOOLBOX_UTIL_UTILITY_HPP
19
20#include <toolbox/Config.h>
21
22#include <bit>
23#include <cstdint>
24#include <string_view>
25
26namespace toolbox {
27inline namespace util {
28
29template <typename T>
30struct AlwaysFalse : std::false_type {};
31
32template <typename ValueT>
33inline auto& remove_const(const ValueT& ref)
34{
35 return const_cast<ValueT&>(ref);
36}
37
38constexpr bool isdigit(int c) noexcept
39{
40 return c >= '0' && c <= '9';
41}
42static_assert(isdigit('0') && isdigit('9') && !isdigit('A'));
43
49constexpr int dec_digits(std::int64_t i) noexcept
50{
51 return i < 10000000000 ? i < 100000 ? i < 100 ? i < 10 ? 1 : 2
52 : i < 1000 ? 3
53 : i < 10000 ? 4
54 : 5
55 : i < 10000000 ? i < 1000000 ? 6 : 7
56 : i < 100000000 ? 8
57 : i < 1000000000 ? 9
58 : 10
59 : i < 1000000000000000 ? i < 1000000000000 ? i < 100000000000 ? 11 : 12
60 : i < 10000000000000 ? 13
61 : i < 100000000000000 ? 14
62 : 15
63 : i < 100000000000000000 ? i < 10000000000000000 ? 16 : 17
64 : i < 1000000000000000000 ? 18
65 : 19;
66}
67
74template <typename UIntegerT>
75 requires std::unsigned_integral<UIntegerT>
76constexpr int hex_digits(UIntegerT i) noexcept
77{
78 constexpr auto Bits = sizeof(i) * 8;
79 return 1 + ((Bits - std::countl_zero(i | 1) - 1) >> 2);
80}
81
82static_assert(hex_digits(0x0U) == 1);
83static_assert(hex_digits(0x1U) == 1);
84static_assert(hex_digits(std::uint64_t{0xffffffffffff}) == 12);
85
86TOOLBOX_API bool stob(std::string_view sv, bool dfl = false) noexcept;
87TOOLBOX_API double stod(std::string_view sv, double dfl = {}) noexcept;
88
89template <typename ValueT>
90 requires std::integral<ValueT> || std::same_as<ValueT, double>
91constexpr ValueT ston(std::string_view sv) noexcept
92{
93 if constexpr (std::is_same_v<ValueT, double>) {
94 return stod(sv);
95 } else if constexpr (std::is_integral_v<ValueT>) {
96 auto it = sv.begin(), end = sv.end();
97 if (it == end) {
98 return 0;
99 }
100 bool neg{false};
101 if constexpr (std::is_signed_v<ValueT>) {
102 // Handle sign.
103 if (*it == '-') {
104 if (++it == end) {
105 return 0;
106 }
107 neg = true;
108 }
109 }
110 std::uint64_t n{0};
111 if (isdigit(*it)) {
112 n = *it++ - '0';
113 while (it != end && isdigit(*it)) {
114 n *= 10;
115 n += *it++ - '0';
116 }
117 }
118 return neg ? -n : n;
119 } else {
120 static_assert(AlwaysFalse<ValueT>::value);
121 }
122}
123static_assert(ston<int>(std::string_view{"-123"}) == -123);
124
125} // namespace util
126} // namespace toolbox
127
128#endif // TOOLBOX_UTIL_UTILITY_HPP
#define TOOLBOX_API
Definition Config.h:39
STL namespace.
bool stob(string_view sv, bool dfl) noexcept
Definition Utility.cpp:26
auto & remove_const(const ValueT &ref)
Definition Utility.hpp:33
constexpr bool isdigit(int c) noexcept
Definition Utility.hpp:38
constexpr int hex_digits(UIntegerT i) noexcept
Definition Utility.hpp:76
constexpr int dec_digits(std::int64_t i) noexcept
Definition Utility.hpp:49
std::string_view sv
Definition Tokeniser.hpp:26
constexpr ValueT ston(std::string_view sv) noexcept
Definition Utility.hpp:91
double stod(std::string_view sv, double dfl) noexcept
Definition Utility.cpp:89
constexpr auto bind() noexcept
Definition Slot.hpp:92