mardi 5 septembre 2017

Pretty-printable std::regex

I would like to be able to print a regex. For legitimate reasons, std::regex does not keep a copy of the textual regular expression, so we have to wrap it ourselves. Yet, simple aggregation is quite verbose. Is there a recommended practice? Would public inheritance, as below, feature nasty issues?

#include <iomanip>
#include <iostream>
#include <string>
#include <regex>

template <
  class CharT,
  class Traits = std::regex_traits<CharT>
  >
class basic_pp_regex
  : public std::basic_regex<CharT, Traits>
{
public:
  using self = basic_pp_regex;
  using super = std::basic_regex<CharT, Traits>;

  template <typename... Args>
  basic_pp_regex(std::string pretty, Args&&... args)
    : super{pretty, std::forward<Args>(args)...}
    , _pretty{std::move(pretty)}
  {}

  basic_pp_regex(basic_pp_regex const&) = default;
  basic_pp_regex(basic_pp_regex&&) = default;
  // The default regex matches nothing.
  basic_pp_regex()
    : basic_pp_regex{"$."}
  {}

  friend
  std::ostream& operator<<(std::ostream& o, self const& s)
  {
    return o << std::quoted(s._pretty, '/');
  }

private:
  std::string _pretty;
};

using pp_regex = basic_pp_regex<char>;

int main()
{
  auto re = pp_regex("/foo");
  auto s = "/root/foo/bar";
  std::cout << s << " ~ " << re << " =  " << std::regex_search(s, re) << '\n';
}

which gives:

/root/foo/bar ~ /\/foo/ =  1

Aucun commentaire:

Enregistrer un commentaire