Modernes C++ programmieren

Okt 20, 2024

lst-0044-godb.cpp

//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/WqjK31Gn6 
// 'Elf' as before…
template<> struct std::formatter<Elf> {
  std::string attribs;                  // Sequence of '%n', '%g', '%e', '%v', and others
  constexpr auto parse(std::format_parse_context& pctx) {
    auto it = std::ranges::find(pctx.begin(), pctx.end(), '}');// search for '}'
    attribs = std::string(pctx.begin(), it);                   // save everything
    return it;                                                 // points to '}'
  }
  auto format(const Elf& elf, std::format_context& fctx) const {
    auto out = fctx.out();                                     // into here
    for(auto n=0u; n<attribs.size()-1; ++n) {
      if(attribs[n] == '%') {             // instruction to output a member
        switch(attribs[++n]) {
          case 'n': out = std::format_to(out, "{}", elf.name); break;
          case 'g': out = std::format_to(out, "{}", elf.birth_year); break;
          case 'e': out = std::format_to(out, "{}", elf.era); break;
          case 'v': out = std::format_to(out, "{}", elf.folk); break;
          case '%': out = std::format_to(out, "%"); break;     // %% becomes %
        }
      } else {
        out = std::format_to(out, "{}", attribs[n]);           // everything else
      }
    }
    return out;                                                // points to the end
  }
};
int main() {
  Elf e{"Feanor", 1169, "EZ", "Nordor"};
  std::cout << std::format("{:Elf %n}", e) << std::endl;
  // Output: Elf Feanor
  std::cout << std::format("Elf {:%n, %v, born %g in the age %e}\n", e);
  // Output: Elf Feanor, Nordor, born 1169 in the age EZ
}