[Development] char8_t summary?

Matthew Woehlke mwoehlke.floss at gmail.com
Tue Jul 16 18:11:37 CEST 2019


On 15/07/2019 18.19, Thiago Macieira wrote:
> On Monday, 15 July 2019 09:41:24 PDT Matthew Woehlke wrote:
>> Note also that I suggested having the template definition out-of-line;
>> it doesn't need to be in (e.g.) qstring.h or anywhere that will affect
>> *user* compile times. Only the TU responsible for instantiating them
>> would be affected, and that should be negligible in the grand scheme of
>> things.
> 
> Then it's no different than an overload, if the implementation isn't the same 
> (and it isn't).

...but a template allows the common portions to be written in a single
definition with overloads *and/or* `if constexpr` used where the code
needs to differ. Regular overloads would require 100% of the definition
to be duplicated for each overload.

In terms of *declarations*, yes, you are going to have the same number
of declarations. However, those are only one line, and potentially can
be generated for each string type using a macro, so O(M+N) (M = methods,
N = string types) rather than O(M*N) actual source lines. (Granted, you
could do this for plain overload declarations also, but a) this probably
doesn't play as well with documentation, and b) you still have to write
O(M*N) definitions rather than O(M).)

Concrete example:

  // .h
  bool contains(QStringView);
  bool contains(QLatin1StringView);

  // .cpp
  bool contains(QStringView needle)
  {
    ...
  }

  bool contains(QStringView needle)
  {
    ...
  }

- vs -

  // .h
  template <typename T>
  bool contains(T);
  extern template bool contains<QStringView>(QStringView);
  extern template bool contains<QStringView>(QLatin1StringView);

  // .cpp
  template <typename T>
  bool contains(T needle)
  {
    int const l = needle.chars();
    int i = 0;
    ... // computation of went_too_far elided
    while (i < went_too_far)
    {
      if (q_compare_strings(this->midRef(i), needle, l)
        return true;
      i = q_next_codepoint(this, i);
    }
    return false;
  }

  template bool contains<QStringView>(QStringView);
  template bool contains<QStringView>(QLatin1StringView);

Keep in mind also that this method lives in a notional (templated?)
QGenericString base class and/or is actually a helper function, i.e. it
is also templated on the type of this/haystack... thus I have this *one
and only one* definition of 'contains', rather than O(N²) definitions.

Hopefully this presents a plausible example of common code. The basic
algorithm (iterate through 'haystack' looking for 'needle') is common
regardless of the string types. The points that differ (e.g. only
starting the search at code points, computing lengths) use overloaded
helper functions which can be inline (e.g. q_next_codepoint for some
types will just be operator++) and optimized. It's also likely that
these helpers will be used in multiple methods.

-- 
Matthew


More information about the Development mailing list