最終更新日時(UTC):
が更新

履歴 編集

class template
<format>

std::range_formatter(C++23)

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

処理系

関連項目

参照