Skip to content

Commit

Permalink
formatter : parseを実装する例を記載
Browse files Browse the repository at this point in the history
  • Loading branch information
faithandbrave committed Jan 23, 2023
1 parent 3fd8e81 commit 322f877
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
2 changes: 1 addition & 1 deletion reference/format/format.md
Expand Up @@ -277,7 +277,7 @@ _`basic_format_string`_ のコンストラクタは[即時関数](/lang/cpp20/im
* 書式文字列は定数式であり、[`string_view`](/reference/string_view/basic_string_view.md)(ワイド文字列版は[`wstring_view`](/reference/string_view/basic_string_view.md))に暗黙変換できること。
* 書式文字列にエラーがないこと。例えば、
* 閉じていないカッコなどの構文エラーがないこと。
* 実際に渡している引数の型が書式文字列中の置換フィールドが要求する型に合うこと
* 実際に渡している引数の型が、書式文字列中の置換フィールドに要求される型と合うこと

## 効果

Expand Down
64 changes: 63 additions & 1 deletion reference/format/formatter.md
Expand Up @@ -131,6 +131,7 @@ namespace std {


## 例
### オリジナル書式なし、型変換のみの場合
```cpp example
#include <iostream>
#include <format>
Expand All @@ -151,12 +152,73 @@ int main()
std::cout << std::format("{}", red) << std::endl;
}
```
* std::format_context[link basic_format_context.md]

### 出力
#### 出力
```
red
```

### オリジナル書式を定義する例
```cpp example
#include <iostream>
#include <format>

enum color { red, green, blue };

const char* color_names[] = { "red", "green", "blue" };
const char* jp_color_names[] = { "赤", "緑", "青" };

template<>
struct std::formatter<color> {
bool is_jp = false;

// コンパイル時の書式文字列の解析があるため、
// constexprにする必要がある。
// この関数に渡されるパラメータは、{:%j}の%以降。
// 解析がおわった場所を指すイテレータを返す。
constexpr auto parse(std::format_parse_context& ctx) {
auto it = ctx.begin();
if (*it == '%') {
++it;
if (*it == 'j') {
is_jp = true;
}
else if (*it == 'e') {
is_jp = false;
}
++it;
}
return it;
}

// format()関数は書式の情報をもたない。
// parse()関数で解析した書式をメンバ変数で保持しておいて、
// それをもとに書式化する
auto format(color c, std::format_context& ctx) const {
return std::format_to(ctx.out(), "{}",
is_jp ? jp_color_names[c] : color_names[c]
);
}
};

int main()
{
std::cout << std::format("{:%j} {:%e}", red, blue) << std::endl;
}
```
* std::format_parse_context[link basic_format_parse_context.md]
* ctx.begin()[link basic_format_parse_context/begin.md.nolink]
* std::format_context[link basic_format_context.md]
* ctx.out()[link basic_format_context/out.md]
* std::format_to[link format_to.md]


#### 出力
```
赤 blue
```

## バージョン
### 言語
- C++20
Expand Down

0 comments on commit 322f877

Please sign in to comment.