Skip to content

Commit 923f152

Browse files
committed
charconv : C++26対応としてfrom_chars_result / to_chars_resultにoperator boolを追加 (close #1179)
1 parent 86e7cee commit 923f152

File tree

6 files changed

+397
-3
lines changed

6 files changed

+397
-3
lines changed

reference/charconv/from_chars.md

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ C++標準はこれら関数の実装の詳細について何も規定しない
118118
119119
## 例
120120
121-
### 基本の使用例
121+
### 基本の使用例 (C++17)
122122
123123
```cpp example
124124
#include <iostream>
@@ -276,6 +276,164 @@ nan
276276
-inf
277277
```
278278

279+
### 基本の使用例 (C++26)
280+
```cpp example
281+
#include <iostream>
282+
#include <iomanip>
283+
#include <charconv>
284+
285+
int main()
286+
{
287+
{
288+
const char str[] = "00000123456789 is decimal";
289+
int value{};
290+
291+
//(1) 10進数文字列からintへ変換
292+
//変換変換の成否判定に`operator bool`を使用
293+
if (std::from_chars(std::begin(str), std::end(str), value)) {
294+
std::cout << value << std::endl;
295+
}
296+
else {
297+
std::cout << "conversion failed." << std::endl;
298+
}
299+
}
300+
301+
{
302+
const char str[] = "1111111111111111 is (65535)_10";
303+
int value{};
304+
305+
//(1) 2進数文字列からintへ変換
306+
if (std::from_chars(std::begin(str), std::end(str), value, 2)) {
307+
std::cout << value << std::endl;
308+
}
309+
else {
310+
std::cout << "conversion failed." << std::endl;
311+
}
312+
}
313+
314+
{
315+
const char str[] = "Z is (35)_10";
316+
int value{};
317+
318+
//(1) 36進数文字列からintへ変換
319+
if (std::from_chars(std::begin(str), std::end(str), value, 36)) {
320+
std::cout << value << std::endl;
321+
}
322+
else {
323+
std::cout << "conversion failed." << std::endl;
324+
}
325+
}
326+
327+
{
328+
const char str[] = "255";
329+
char value{};
330+
331+
//(1) 失敗する例 MSVCにおけるcharの範囲は-128~127
332+
if (std::from_chars(std::begin(str), std::end(str), value)) {
333+
std::cout << value << std::endl;
334+
}
335+
else {
336+
std::cout << "conversion failed." << std::endl;
337+
}
338+
}
339+
340+
std::cout << std::setprecision(16);
341+
342+
{
343+
const char str[] = "3.1415926535897932384626433832795 is pi";
344+
double value{};
345+
346+
//(3) 固定小数表記文字列からdoubleへ変換
347+
if (std::from_chars(std::begin(str), std::end(str), value)) {
348+
std::cout << value << std::endl;
349+
}
350+
else {
351+
std::cout << "conversion failed." << std::endl;
352+
}
353+
}
354+
355+
{
356+
const char str[] = "1.10001e-01 is Liouville number";
357+
double value{};
358+
359+
//(3) 指数表記文字列からdoubleへ変換
360+
if (std::from_chars(std::begin(str), std::end(str), value)) {
361+
std::cout << value << std::endl;
362+
}
363+
else {
364+
std::cout << "conversion failed." << std::endl;
365+
}
366+
}
367+
368+
{
369+
const char str[] = "1.c29068986fcdf000p-4 is Liouville number";
370+
double value{};
371+
372+
//(3) 16進指数表記文字列からdoubleへ変換
373+
if (std::from_chars(std::begin(str), std::end(str), value, std::chars_format::hex)) {
374+
std::cout << value << std::endl;
375+
}
376+
else {
377+
std::cout << "conversion failed." << std::endl;
378+
}
379+
}
380+
381+
{
382+
const char str[] = " 3.1415926535897932384626433832795 is pi";
383+
double value{};
384+
385+
//(3) 失敗する例 ホワイトスペース読み飛ばし
386+
if (std::from_chars(std::begin(str), std::end(str), value)) {
387+
std::cout << value << std::endl;
388+
}
389+
else {
390+
std::cout << "conversion failed." << std::endl;
391+
}
392+
}
393+
394+
{
395+
const char str[] = "NaN";
396+
double value{};
397+
398+
//(3) NaNの読み取り
399+
if (std::from_chars(std::begin(str), std::end(str), value)) {
400+
std::cout << value << std::endl;
401+
}
402+
else {
403+
std::cout << "conversion failed." << std::endl;
404+
}
405+
}
406+
407+
{
408+
const char str[] = "-INF";
409+
double value{};
410+
411+
//(3) INFの読み取り
412+
if (std::from_chars(std::begin(str), std::end(str), value)) {
413+
std::cout << value << std::endl;
414+
}
415+
else {
416+
std::cout << "conversion failed." << std::endl;
417+
}
418+
}
419+
}
420+
```
421+
422+
#### 出力例
423+
```
424+
123456789
425+
65535
426+
35
427+
conversion failed.
428+
3.141592653589793
429+
0.110001
430+
0.110001
431+
conversion failed.
432+
nan
433+
-inf
434+
```
435+
436+
279437
### イテレータ範囲からの変換(C++20)
280438

281439
入力文字列はポインタによる範囲で指定する必要があるが、`std::string`等のイテレータは必ずしもポインタとは限らず、そのままでは使いづらいことがある。その様なとき、C++20の[`std::to_address`](/reference/memory/to_address.md)を使用すると安全かつ簡易にこの関数でイテレータを使用できる。

reference/charconv/from_chars_result.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ namespace std {
2525
| ec | 成功なら`ec == errc{}`、失敗ならば`errc::invalid_argument`を表す[`errc`](/reference/system_error/errc.md)の値。 | C++17 |
2626
2727
## メンバ関数
28+
### 成否判定
29+
30+
| 名前 | 説明 | 対応バージョン |
31+
|------|------|----------------|
32+
| [`operator bool`](from_chars_result/op_bool.md) | 変換に成功したかを判定する | C++26 |
33+
34+
2835
### 比較演算子
2936
3037
| 名前 | 説明 | 対応バージョン |
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# operator bool
2+
* charconv[meta header]
3+
* std[meta namespace]
4+
* from_chars_result[meta class]
5+
* function[meta id-type]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
constexpr explicit operator bool() const noexcept;
10+
```
11+
12+
## 概要
13+
変換が成功したかを判定する。
14+
15+
16+
## 戻り値
17+
```cpp
18+
return ec == errc{};
19+
```
20+
* errc[link /reference/system_error/errc.md]
21+
22+
23+
##
24+
```cpp example
25+
#include <iostream>
26+
#include <charconv>
27+
28+
int main()
29+
{
30+
const char str[] = "123";
31+
int value{};
32+
if (std::from_chars(std::begin(str), std::end(str), value)) {
33+
std::cout << value << std::endl;
34+
}
35+
else {
36+
std::cout << "conversion failed" << std::endl;
37+
}
38+
}
39+
```
40+
* std::from_chars[link /reference/charconv/from_chars.md]
41+
42+
### 出力
43+
```
44+
123
45+
```
46+
47+
## バージョン
48+
### 言語
49+
- C++26
50+
51+
### 処理系
52+
- [Clang](/implementation.md#clang): ??
53+
- [GCC](/implementation.md#gcc): ??
54+
- [Visual C++](/implementation.md#visual_cpp): ??
55+
56+
57+
## 参照
58+
- [P2497R0 Testing for success or failure of `<charconv>` functions](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2497r0.html)

reference/charconv/to_chars.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ C++標準はこれら関数の実装の詳細について何も規定しない
175175
176176
177177
## 例
178-
178+
### 基本の使用例 (C++17)
179179
```cpp example
180180
#include <iostream>
181181
#include <charconv>
@@ -268,7 +268,111 @@ int main()
268268
* std::chars_format[link chars_format.md]
269269
* std::errc[link /reference/system_error/errc.md]
270270

271-
### 出力例(VS2019 16.5 preview 1)
271+
#### 出力例(VS2019 16.5 preview 1)
272+
```
273+
10
274+
1111111111111111
275+
z
276+
0.110001
277+
1.10001e-01
278+
0.110001
279+
1.c29068986fcdfp-4
280+
1.1000100000000000e-01
281+
0.1100010000000000
282+
1.c29068986fcdf000p-4
283+
```
284+
285+
### 基本の使用例 (C++26)
286+
```cpp example
287+
#include <iostream>
288+
#include <charconv>
289+
290+
int main()
291+
{
292+
char out[50]{};
293+
auto begin = std::begin(out);
294+
auto end = std::end(out);
295+
296+
//(1) 10進数文字列へ変換
297+
if (auto result = std::to_chars(begin, end, 10)) {
298+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
299+
}
300+
else {
301+
std::cout << "conversion failed." << std::endl;
302+
}
303+
//(1) 2進数文字列へ変換
304+
if (auto result = std::to_chars(begin, end, 65535, 2)) {
305+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
306+
}
307+
else {
308+
std::cout << "conversion failed." << std::endl;
309+
}
310+
//(1) 36進数文字列へ変換
311+
if (auto result = std::to_chars(begin, end, 35, 36)) {
312+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
313+
}
314+
else {
315+
std::cout << "conversion failed." << std::endl;
316+
}
317+
318+
//リウヴィル数
319+
constexpr double l = 0.11000100000000000000000100000000000;
320+
321+
//(3) 精度・フォーマット指定なしの浮動小数点数変換
322+
if (auto result = std::to_chars(begin, end, l)) {
323+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
324+
}
325+
else {
326+
std::cout << "conversion failed." << std::endl;
327+
}
328+
329+
//(7) 精度指定なしの浮動小数点数変換、指数表記
330+
if (auto result = std::to_chars(begin, end, l, std::chars_format::scientific)) {
331+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
332+
}
333+
else {
334+
std::cout << "conversion failed." << std::endl;
335+
}
336+
//(7) 精度指定なしの浮動小数点数変換、固定小数表記
337+
if (auto result = std::to_chars(begin, end, l, std::chars_format::fixed)) {
338+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
339+
}
340+
else {
341+
std::cout << "conversion failed." << std::endl;
342+
}
343+
//(7) 精度指定なしの浮動小数点数変換、16進指数表記
344+
if (auto result = std::to_chars(begin, end, l, std::chars_format::hex)) {
345+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
346+
}
347+
else {
348+
std::cout << "conversion failed." << std::endl;
349+
}
350+
351+
//(11) 精度指定ありの浮動小数点数変換、指数表記
352+
if (auto result = std::to_chars(begin, end, l, std::chars_format::scientific, 16)) {
353+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
354+
}
355+
else {
356+
std::cout << "conversion failed." << std::endl;
357+
}
358+
//(11) 精度指定ありの浮動小数点数変換、固定小数表記
359+
if (auto result = std::to_chars(begin, end, l, std::chars_format::fixed, 16)) {
360+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
361+
}
362+
else {
363+
std::cout << "conversion failed." << std::endl;
364+
}
365+
//(11) 精度指定ありの浮動小数点数変換、16進指数表記
366+
if (auto result = std::to_chars(begin, end, l, std::chars_format::hex, 16)) {
367+
std::cout << std::string_view(begin, result.ptr - begin) << std::endl;
368+
}
369+
else {
370+
std::cout << "conversion failed." << std::endl;
371+
}
372+
}
373+
```
374+
375+
#### 出力例
272376
```
273377
10
274378
1111111111111111

reference/charconv/to_chars_result.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ namespace std {
2424
| ec | 成功なら`ec == errc{}`、失敗ならば`errc::value_too_large`を表す[`errc`](/reference/system_error/errc.md)の値。 | C++17 |
2525
2626
## メンバ関数
27+
### 成否判定
28+
29+
| 名前 | 説明 | 対応バージョン |
30+
|------|------|----------------|
31+
| [`operator bool`](to_chars_result/op_bool.md) | 変換に成功したかを判定する | C++26 |
32+
33+
2734
### 比較演算子
2835
2936
| 名前 | 説明 | 対応バージョン |

0 commit comments

Comments
 (0)