jaulib v1.4.1-17-gd77ace3-dirty
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_stringconv_to.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <cassert>
25#include <cinttypes>
26#include <cstring>
27#include <limits>
28
29#include "test_datatype01.hpp"
30
31#include <jau/basic_types.hpp>
32#include <jau/cpp_lang_util.hpp>
33#include <jau/string_cfmt.hpp>
34#include <jau/string_util.hpp>
35#include <jau/test/catch2_ext.hpp>
37
38typedef std::vector<int> std_vec_int;
39
40typedef std_vec_int::iterator std_vec_int_iter;
41
42typedef std_vec_int::const_iterator std_vec_int_citer;
43
44typedef std_vec_int_citer::pointer std_vec_int_citer_pointer;
45
46typedef decltype( std::declval<std_vec_int_citer>().operator->() ) std_vec_int_citer_ptrop_retval;
47
48using namespace jau::int_literals;
49
50TEST_CASE( "Test 00 - to_string", "[jau][string][to_string]" ) {
51 int i1 = 1;
52 uint64_t u64_1 = 1116791496961ull;
53 void * p_v_1 = (void *)0xAFFE;
54 float float_1 = 1.65f;
55
56 Addr48Bit addr48bit_1(u64_1);
57
58 CHECK("1" == jau::to_string<int>(i1));
59 CHECK("1116791496961" == jau::to_string(u64_1));
60 CHECK("0xaffe" == jau::to_string(p_v_1));
61 CHECK("0xaffe" == jau::toHexString(0xaffe_u32));
62 {
63 // radix, default: no-width, prefix, no-separator, '0' padding
64 CHECK("0xaffe" == jau::to_string(0xaffe_u32, 16)); // hex
65 CHECK("876543210" == jau::to_string(876543210_u64, 10)); // dec
66 CHECK("077652" == jau::to_string(077652_u32, 8)); // oct
67 CHECK("0b11010101101" == jau::to_string(0b11010101101_u32, 2)); // bin
68
69 // no-prefix, radix, default: no-width, no-separator, '0' padding
70 CHECK("affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none)); // hex
71 CHECK("876543210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none)); // dec
72 CHECK("77652" == jau::to_string(077652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none)); // oct
73 CHECK("11010101101" == jau::to_string(0b11010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none)); // bin
74
75 // radix, width-expansion, default: prefix, no-separator, '0' padding
76 CHECK("0x00affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 8)); // hex
77 CHECK("000876543210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 12)); // dec
78 CHECK("0000077652" == jau::to_string(077652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 10)); // oct
79 CHECK("0b00011010101101" == jau::to_string(0b11010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 16)); // bin
80
81 // no-prefix, radix, width-expansion, default: no-separator, '0' padding
82 CHECK("0000affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 8)); // hex
83 CHECK("000876543210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 12)); // dec
84 CHECK("0000077652" == jau::to_string(077652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 10)); // oct
85 CHECK("0000011010101101" == jau::to_string(0b11010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 16)); // bin
86
87 // radix, separator, default: no-width, prefix, '0' padding
88 CHECK("0xaffe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // hex
89 CHECK("0x1'affe" == jau::to_string(0x1affe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // hex
90 CHECK("876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // dec
91 CHECK("1'876'543'210" == jau::to_string(1876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // dec
92 CHECK("04321'7652" == jau::to_string(043217652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // oct
93 CHECK("01'4321'7652" == jau::to_string(0143217652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // oct
94 CHECK("0b1010'1101" == jau::to_string(0b10101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // bin
95 CHECK("0b1'1010'1101" == jau::to_string(0b110101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 0, '\'')); // bin
96
97 // no-prefix, radix, separator, default: no-width, '0' padding
98 CHECK("affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // hex
99 CHECK("1'affe" == jau::to_string(0x1affe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // hex
100 CHECK("876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // dec
101 CHECK("1'876'543'210" == jau::to_string(1876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // dec
102 CHECK("4321'7652" == jau::to_string(043217652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // oct
103 CHECK("1'4321'7652" == jau::to_string(0143217652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // oct
104 CHECK("1010'1101" == jau::to_string(0b10101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // bin
105 CHECK("1'1010'1101" == jau::to_string(0b110101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 0, '\'')); // bin
106
107 // radix, width-expansion, separator, default: prefix, '0' padding
108 CHECK("0xaffe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 6, '\'')); // hex
109 CHECK("0x'affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 7, '\'')); // hex
110 CHECK("0x0'affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 8, '\'')); // hex
111
112 CHECK("876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 11, '\'')); // dec
113 CHECK("'876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 12, '\'')); // dec
114 CHECK("0'876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 13, '\'')); // dec
115
116 CHECK("07652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 5, '\'')); // oct
117 CHECK("0'7652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 6, '\'')); // oct
118 CHECK("00'7652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 7, '\'')); // oct
119
120 CHECK("0b1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 16, '\'')); // bin
121 CHECK("0b'1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 17, '\'')); // bin
122 CHECK("0b0'1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::prefix, 18, '\'')); // bin
123
124 // no-prefix, radix, width-expansion, separator, default: '0' padding
125 CHECK("affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 4, '\'')); // hex
126 CHECK("'affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 5, '\'')); // hex
127 CHECK("0'affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 6, '\'')); // hex
128
129 CHECK("876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 11, '\'')); // dec
130 CHECK("'876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 12, '\'')); // dec
131 CHECK("0'876'543'210" == jau::to_string(876543210_u64, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 13, '\'')); // dec
132
133 CHECK("7652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 4, '\'')); // oct
134 CHECK("'7652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 5, '\'')); // oct
135 CHECK("0'7652" == jau::to_string(07652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 6, '\'')); // oct
136
137 CHECK("1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 14, '\'')); // bin
138 CHECK("'1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 15, '\'')); // bin
139 CHECK("0'1110'1010'1101" == jau::to_string(0b111010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 16, '\'')); // bin
140
141 // no-prefix, radix, width-expansion, padding ' '
142 CHECK(" affe" == jau::to_string(0xaffe_u32, 16, jau::LoUpCase::lower, jau::PrefixOpt::none, 8, '\'', ' '));
143 CHECK(" 876'543'210" == jau::to_string(876543210_u32, 10, jau::LoUpCase::lower, jau::PrefixOpt::none, 15, '\'', ' '));
144 CHECK(" 110'1010'1101" == jau::to_string(0b11010101101_u32, 2, jau::LoUpCase::lower, jau::PrefixOpt::none, 17, '\'', ' '));
145 CHECK(" 7'7652" == jau::to_string(077652_u32, 8, jau::LoUpCase::lower, jau::PrefixOpt::none, 10, '\'', ' '));
146 }
147 CHECK("1.650000" == jau::to_string(float_1));
148
149 CHECK("01:04:05:F5:E1:01" == jau::to_string(addr48bit_1));
150
151 //
152 // Validating 'pointer std::vector::const_iterator.operator->()'
153 // and the to_string type trait logic of it.
154 //
155
156 // jau::type_cue<std_vec_int_citer>::print("std_vec_int_citer", jau::TypeTraitGroup::ALL);
157 // jau::type_cue<std_vec_int_citer_pointer>::print("std_vec_int_citer_pointer", jau::TypeTraitGroup::ALL);
158
159 // jau::type_cue<std_vec_int_citer_ptrop_retval>::print("std_vec_int_citer_ptrop_retval", jau::TypeTraitGroup::ALL);
160 printf("jau::has_member_of_pointer<std_vec_int_citer>) %d\n", jau::has_member_of_pointer<std_vec_int_citer>::value);
161
162 std_vec_int vec_int_1;
163 vec_int_1.push_back(1); vec_int_1.push_back(2); vec_int_1.push_back(3);
164 std_vec_int_citer vec_int_citer_1B = vec_int_1.cbegin();
165 uint8_t* vec_int_citer_1B_ptr = (uint8_t*)(vec_int_citer_1B.operator->());
166 std::string vec_int_citer_1B_str = jau::toHexString(vec_int_citer_1B_ptr);
167
168 std_vec_int_citer vec_int_citer_1E = vec_int_1.cend();
169 uint8_t* vec_int_citer_1E_ptr = (uint8_t*)(vec_int_citer_1E.operator->());
170 std::string vec_int_citer_1E_str = jau::toHexString(vec_int_citer_1E_ptr);
171
172 std::ptrdiff_t vec_int_citer_1E_1B_ptrdiff = vec_int_citer_1E_ptr - vec_int_citer_1B_ptr;
173 size_t vec_int_citer_1E_1B_ptr_count = vec_int_citer_1E_1B_ptrdiff / sizeof(int);
174 size_t vec_int_citer_1E_1B_itr_count = vec_int_citer_1E - vec_int_citer_1B;
175
176 printf("vec_int_citer_1E - vec_int_citer_1B = itr_count %zu, ptr_count %zu\n",
177 vec_int_citer_1E_1B_itr_count, vec_int_citer_1E_1B_ptr_count);
178 printf("vec_int_citer_1E - vec_int_citer_1B = %zu\n", vec_int_citer_1E_1B_itr_count);
179 printf("vec_int_citer_1B_ptr %s, vec_int_citer_1E1_ptr = %s\n", vec_int_citer_1B_str.c_str(), vec_int_citer_1E_str.c_str());
180
181 CHECK(vec_int_citer_1E_1B_itr_count == 3);
182 CHECK(vec_int_citer_1E_1B_itr_count == vec_int_citer_1E_1B_ptr_count);
183
184 CHECK(vec_int_citer_1E_str == jau::to_string(vec_int_citer_1E));
185}
186
187#if 0
188TEST_CASE( "Test 01 - to_string(radix)", "[jau][string][to_string(radix)]" ) {
189 REQUIRE( true == true );
190}
191
192TEST_CASE( "Test 02 - toHexString()", "[jau][string][toHexString]" ) {
193 REQUIRE( true == true );
194}
195#endif
196
197static void testToBitString(std::string_view prefix, std::string_view exp_be_s, const uint64_t &exp_be_v, size_t max_bits, bool check_value=true) {
198 std::cout << prefix << ": max_bits " << max_bits << "\n";
199 std::string has_be_s1 = jau::toBitString(exp_be_v, jau::bit_order_t::msb, jau::PrefixOpt::none, max_bits);
200 std::cout << " exp_be_s : " << exp_be_s << "\n";
201 std::cout << " has_be_s1: " << has_be_s1 << "\n";
202 REQUIRE( exp_be_s == has_be_s1 );
203
204 if( check_value ) {
205 const auto [has_be_v, len_be, ok_be] = jau::fromBitString(exp_be_s);
206 REQUIRE(true == ok_be);
207 REQUIRE(exp_be_s.size() == len_be);
208 std::string has_be_s2 = jau::toBitString(has_be_v, jau::bit_order_t::msb, jau::PrefixOpt::none, max_bits);
209 std::cout << " has_be_s2: " << has_be_s2 << "\n";
210 REQUIRE(exp_be_v == has_be_v);
211 }
212}
213static void testToBitString(std::string_view prefix, std::string_view s_be1, const uint32_t &v_be1) {
214 testToBitString(prefix, s_be1, v_be1, s_be1.size(), true);
215}
216
217TEST_CASE( "Test 03 - toBitString()", "[jau][string][toBitString]" ) {
218 {
219 testToBitString("Test 03.01.01", "000101100101110111011001", 0b101100101110111011001_u64, 0);
220 testToBitString("Test 03.01.02", "000101100101110111011001", 0b101100101110111011001_u64);
221 testToBitString("Test 03.01.03", "101110111011001", 0b101100101110111011001_u64, 15, false);
222 testToBitString("Test 03.01.04", "00000000000101100101110111011001", 0b101100101110111011001_u64);
223 testToBitString("Test 03.01.05", "000000000000101100101110111011001", 0b101100101110111011001_u64, 33);
224
225 testToBitString("Test 03.02.01", "11011001011101110110011110001101", 0b11011001011101110110011110001101_u64, 0);
226 testToBitString("Test 03.02.02", "11011001011101110110011110001101", 0b11011001011101110110011110001101_u64, 32);
227 testToBitString("Test 03.02.03", "01011001011101110110011110001101", 0b01011001011101110110011110001101_u64, 0);
228 testToBitString("Test 03.02.04", "01011001011101110110011110001101", 0b01011001011101110110011110001101_u64, 32);
229 testToBitString("Test 03.02.05", "0101110111011001", 0b0101100101110111011001_u64, 16, false);
230
231 testToBitString("Test 03.03.01", "1101100101110111011001111000110111011001011101110110011110001101",
232 0b1101100101110111011001111000110111011001011101110110011110001101_u64, 0);
233 testToBitString("Test 03.03.02", "1101100101110111011001111000110111011001011101110110011110001101",
234 0b1101100101110111011001111000110111011001011101110110011110001101_u64, 64);
235
236 testToBitString("Test 03.03.03", "0101100101110111011001111000110111011001011101110110011110001101",
237 0b0101100101110111011001111000110111011001011101110110011110001101_u64, 0);
238 testToBitString("Test 03.03.04", "0101100101110111011001111000110111011001011101110110011110001101",
239 0b0101100101110111011001111000110111011001011101110110011110001101_u64, 64);
240
241 testToBitString("Test 03.03.05", "0001100101110111011001111000110111011001011101110110011110001101",
242 0b0001100101110111011001111000110111011001011101110110011110001101_u64, 0);
243 testToBitString("Test 03.03.06", "0001100101110111011001111000110111011001011101110110011110001101",
244 0b0001100101110111011001111000110111011001011101110110011110001101_u64, 64);
245
246 testToBitString("Test 03.03.07", "1111111111101010111101101011111000000000000000000000000000000000",
247 0b1111111111101010111101101011111000000000000000000000000000000000_u64, 0);
248 testToBitString("Test 03.03.08", "1111111111101010111101101011111000000000000000000000000000000000",
249 0b1111111111101010111101101011111000000000000000000000000000000000_u64, 64);
250
251 testToBitString("Test 03.03.09", "11111110101001111110101011110110",
252 0b0000000000000000000000000000000011111110101001111110101011110110_u64, 0);
253 testToBitString("Test 03.03.10", "0000000000000000000000000000000011111110101001111110101011110110",
254 0b0000000000000000000000000000000011111110101001111110101011110110_u64, 64);
255 testToBitString("Test 03.03.11", "011111110101001111110101011110110",
256 0b0000000000000000000000000000000011111110101001111110101011110110_u64, 33);
257
258 testToBitString("Test 03.03.12", "00000000",
259 0b0000000000000000000000000000000000000000000000000000000000000000_u64, 0);
260 testToBitString("Test 03.03.13", "0000000000000000000000000000000000000000000000000000000000000000",
261 0b0000000000000000000000000000000000000000000000000000000000000000_u64, 64);
262 }
263}
264
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
@ msb
Identifier for most-significant-bit (msb) first.
std::string toBitString(const void *data, const nsize_t length, const bit_order_t bitOrder=bit_order_t::msb, const PrefixOpt prefix=PrefixOpt::prefix, size_t bit_len=0) noexcept
Produce a binary string representation of the given lsb-first byte values.
SizeBoolPair fromBitString(std::vector< uint8_t > &out, const uint8_t bitstr[], const size_t bitstr_len, const bit_order_t bitOrder=bit_order_t::msb, const Bool checkPrefix=Bool::True) noexcept
Converts a given binary string representation into a byte vector, lsb-first.
std::string toHexString(const void *data, const nsize_t length, const lb_endian_t byteOrder=lb_endian_t::big, const LoUpCase capitalization=LoUpCase::lower, const PrefixOpt prefix=PrefixOpt::prefix) noexcept
Produce a hexadecimal string representation of the given lsb-first byte values.
Checker for member of pointer '->' operator with convertible pointer return, no arguments.
int printf(const char *format,...)
Operating Systems predefined macros.
std::vector< int > std_vec_int
static void testToBitString(std::string_view prefix, std::string_view exp_be_s, const uint64_t &exp_be_v, size_t max_bits, bool check_value=true)
std_vec_int_citer::pointer std_vec_int_citer_pointer
decltype(std::declval< std_vec_int_citer >().operator->()) std_vec_int_citer_ptrop_retval
std_vec_int::const_iterator std_vec_int_citer
TEST_CASE("Test 00 - to_string", "[jau][string][to_string]")
std_vec_int::iterator std_vec_int_iter