namespace std {
template <class T, class charT = char>
requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
class range_formatter;
}
概要
range_formatter
は、Range・コンテナに対するformatter
クラスの特殊化を実装するためのユーティリティクラスである。
このクラスは、説明専用クラスrange-default-formatter
の内部実装として使用される。
ユーザー定義のコンテナ・RangeをRange書式に対応する場合は、以下のようにする:
- オリジナル書式を定義しないのであれば、このクラスではなく、
format_kind
を特殊化する - オリジナル書式を定義するのであれば、このクラスおよび
format_kind
を特殊化してparse()
メンバ関数とformat()
メンバ関数を実装する
メンバ関数
メンバ関数 | 説明 | 対応バージョン |
---|---|---|
set_separator |
要素の区切り文字を設定する | C++23 |
set_brackets |
全体の囲み文字を設定する | C++23 |
underlying |
要素型のformatter を取得する |
C++23 |
parse |
書式の解析を行う | C++23 |
format |
書式化を行う | C++23 |
例
オリジナル書式を定義する例
#include <iostream>
#include <format>
#include <vector>
template <class T>
class MyVector {
std::vector<T> v_;
public:
using base_type = std::vector<T>;
using iterator = typename base_type::iterator;
using const_iterator = typename base_type::iterator;
using value_type = typename base_type::value_type;
using reference = typename base_type::reference;
using const_reference = typename base_type::const_reference;
MyVector() = default;
MyVector(std::initializer_list<T> init)
: v_(init.begin(), init.end()) {}
iterator begin() { v_.begin(); }
const_iterator begin() const { v_.begin(); }
iterator end() { v_.end(); }
const_iterator end() const { v_.end(); }
const std::vector<T>& base() const { return v_; }
};
template <class T>
constexpr std::range_format std::format_kind<MyVector<T>> = std::range_format::sequence;
template <class T>
class std::range_formatter<MyVector<T>> : public std::range_formatter<std::vector<T>> {
bool is_colon = false;
using base_type = std::range_formatter<std::vector<T>>;
public:
// コンパイル時の書式文字列の解析があるため、
// constexprにする必要がある。
// この関数に渡されるパラメータは、{:%j}の%以降。
// 解析がおわった場所を指すイテレータを返す。
constexpr auto parse(std::format_parse_context& pctx) {
auto it = pctx.begin();
if (*it == 'c') {
is_colon = true;
++it;
}
pctx.advance_to(it);
return base_type::parse(pctx);
}
// format()関数は書式の情報をもたない。
// parse()関数で解析した書式をメンバ変数で保持しておいて、
// それをもとに書式化する
auto format(const MyVector<T>& v, std::format_context& fctx) const {
if (is_colon) {
auto out = fctx.out();
bool is_first = true;
for (const T& x : v) {
if (is_first) {
is_first = false;
}
else {
*out = ':';
++out;
}
fctx.advance_to(out);
out = underlying().format(x, fctx);
}
return out;
}
return base_type::format(v.base(), fctx);
}
};
#include <cstdint>
int main()
{
std::vector<std::uint8_t> v = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
std::cout << std::format("{:c:02x}", v) << std::endl;
}
出力
aa:bb:cc:dd:ee:ff
(動作確認はできていない)
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??
関連項目
参照
- P2286R8 Formatting Ranges
- P2585R1 Improve default container formatting
- C++23から、Range・コンテナ、
pair
、tuple
のフォーマット出力、および文字・文字列のデバッグ指定 ("?"
) が追加された
- C++23から、Range・コンテナ、