Skip to content

Latest commit

 

History

History
129 lines (108 loc) · 4.4 KB

range_formatter.md

File metadata and controls

129 lines (108 loc) · 4.4 KB

range_formatter

  • format[meta header]
  • class template[meta id-type]
  • std[meta namespace]
  • cpp23[meta cpp]
namespace std {
  template <class T, class charT = char>
    requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
  class range_formatter;
}
  • formattable[link formattable.md]

概要

range_formatterは、Range・コンテナに対する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 std::range_formatter<std::vector<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 std::vector<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, fctx);
  }
};

int main()
{
  std::vector<std::uint8_t> v = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
  std::cout << std::format("{:c:02x}", v) << std::endl;
}
  • std::format_parse_context[link basic_format_parse_context.md]
  • pctx.begin()[link basic_format_parse_context/begin.md]
  • pctx.advance_to()[link basic_format_parse_context/advance_to.md]
  • std::format_context[link basic_format_context.md]
  • fctx.out()[link basic_format_context/out.md]
  • fctx.advance_to()[link basic_format_context/advance_to.md]
  • std::format_to[link format_to.md]
  • std::format[link format.md]
  • underlying()[link range_formatter/underlying.md.nolink]

出力

aa:bb:cc:dd:ee:ff

(動作確認はできていない)

バージョン

言語

  • C++23

処理系

関連項目

参照