<div dir="ltr"><div class="gmail_extra"><div><div><div>> ** Wrapping std::{unordered_}map may be acceptable<br><br>Hmmm... from these benchmarks, QHash seems to regularly beat std::unordered_map so is it really worth it ? <br>=>  <a href="https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html">https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html</a><br><br>Besides, with the Qt implementation the performance is more-or-less consistent across platforms ; if it were to use <br>std containers with moderately advanced algorithms, there could be much more differences depending on the various implementations</div><div>(the worse offender being std::regex... these damn things just don't work the same on any platform).<br></div><div><br></div>More generally, since all these containers are header-only due to their templated nature, wouldn't it be interesting and benefiting to the greater C++ community to <br></div>spin them off in their own small header-only utility library ? <br>Having an explicit choice between COW and no-COW would be valuable in many places where people don't want to bring large stuff like whole QtCore but where a few headers are OK imho; <br>offering facades to std:: types with easy, readable Qt-like APIs would also be quite nice (ideally with a set of standard-compliant typedefs, eg qt::hash_map... one can dream :p).<br><br></div>Best,<div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><br></div><div><font color="#783f04"><br></font></div><div><font size="2" color="#134f5c" face="arial, helvetica, sans-serif">-------</font></div><font size="2" color="#134f5c" face="arial, helvetica, sans-serif">Jean-Michaël Celerier</font><div><font size="2" color="#134f5c" face="arial, helvetica, sans-serif"><a href="http://www.jcelerier.name" target="_blank">http://www.jcelerier.name</a></font></div></div></div></div>
<br><div class="gmail_quote">On Tue, Oct 10, 2017 at 2:49 PM, Thiago Macieira <span dir="ltr"><<a href="mailto:thiago.macieira@intel.com" target="_blank">thiago.macieira@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">[we combined the main and containers session; we did not have time for<br>
QIODevice]<br>
<br>
== Intro ==<br>
Suggested topics:<br>
* QIODevice for Qt 6<br>
* adding std::hash for Qt types<br>
* expanding the hash seed to 64- or 128-bit<br>
<br>
Move to the containers session:<br>
* use qssize_t<br>
<br>
Quick conclusions:<br>
* QRandomGenerator and providing a PRNG of good quality (Mersenne Twister or<br>
Chacha20)<br>
** Yes if our compilers support<br>
* hashing function update:<br>
** Use SipHash-1-2, benchmark 32-bit SipHash<br>
** See if Allan is interested in implementing with ARM AES<br>
<br>
== Use of standard C++ API ==<br>
<br>
We will not add compilers that are worse than what we have today.<br>
* If all the compilers we have support things like std::mersenne_twister, then<br>
all will<br>
* We can add hard-fail configure test<br>
* Should we start migrating from QSharedPointer to std::shared_ptr?<br>
** Deprecate<br>
** Deprecate QScopedPointer<br>
* What about API from C++17/20 that we'd like to use?<br>
** Try to backport the API into a QtPrivate namespace (if it's been<br>
standardised) unless we want to add significant functionality a la QStringView<br>
** If it's not standardised yet, use Qt-style naming<br>
* API naming<br>
** std:: API naming is subtly different from Qt API (hopefully nothing that is<br>
confusing or misleading)<br>
** We could try to create wrappers (container.empty() → container.isEmpty())<br>
<br>
== Modifiers vs getters for QString/QStringView/QByteArray ==<br>
We don't want people to write:<br>
  str = std::move(str).simplified()<br>
We want instead:<br>
  str.simplify()<br>
<br>
So we want to add the full set of modifiers.<br>
<br>
Do we want to add freestanding functions that may operate on std::string and<br>
other string types?<br>
* Like qSimplify()<br>
* Polluting namespace<br>
* They'd all need to be inline and some could be big<br>
* freestanding brings in ADL and could introduce unexpected isues<br>
* We think members are cleaner and we don't want to add these<br>
<br>
* However, we already have some of those! qStartsWith<br>
** Global namespace *and* documented<br>
** foo.startsWith(bar) vs qStartsWith(foo, bar)<br>
** Same conclusion, probably mark \internal, namespace them<br>
*** But review the changes to see what our arguments were on making them<br>
public<br>
<br>
== QStringView ==<br>
* NEVER return QStringView (but QRegularExpression wants to)<br>
** Consequence of "never return a reference" (but containers do)<br>
** Lifetime issues<br>
    auto s = lineedit.text().left(n);<br>
    s valid?<br>
* We can be flexible on having exceptions:<br>
** The API needs to be specifically designed for dealing with references<br>
** Clear naming, such as QRegularExpression::<wbr>captureView()<br>
<br>
Discussion not finished<br>
<br>
== Containers ==<br>
You cannot have all three:<br>
# Implicit sharing<br>
# Performance<br>
# Data-compatibility with std:: containers<br>
<br>
QList:<br>
*  [<a href="https://codereview.qt-project.org/194984" rel="noreferrer" target="_blank">https://codereview.qt-<wbr>project.org/194984</a> QUIP 9]<br>
<br>
Conclusions:<br>
* If we have QStringView, QArrayView, QByteArrayView, we don't need<br>
fromRawData()<br>
* We use qssize_t everywhere<br>
** Check if we want to rename it to "qssize" (bikeshed warning!) : https://<br>
<a href="http://codereview.qt-project.org/#/c/208050/" rel="noreferrer" target="_blank">codereview.qt-project.org/#/c/<wbr>208050/</a><br>
* Investigate C++ contract assertions<br>
<br>
Containers relevant:<br>
* QArrayData-based containers: QString, QByteArray, QVector<br>
** Backed by the same template implementation (QArrayDataPointer)<br>
** They grow to 3*sizeof(void*): {d pointer, begin pointer, qssize_t };<br>
** Implementations:<br>
    template<typename T> using QVector = QVectorImplementation<T, RefCounted>;<br>
    template<typename T> using QExclusiveVector = QVectorImplementation<T,<br>
NotRefCounted>;<br>
<br>
    QExclusiveVector v;<br>
    v.resize(1024);<br>
    auto ptr = v.data();<br>
    // instead of: auto ptr = const_cast<QChar *>(v.constData())<br>
    QVector v2 = std::move(v);<br>
    v = std::move(v2);<br>
* QStringView<br>
* QHash, QMap<br>
** Wrapping std::{unordered_}map may be acceptable<br>
** Would we want to use qHash as the HashFunction with std::unordered_map?<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Thiago Macieira - thiago.macieira (AT) <a href="http://intel.com" rel="noreferrer" target="_blank">intel.com</a><br>
  Software Architect - Intel Open Source Technology Center<br>
<br>
______________________________<wbr>_________________<br>
Development mailing list<br>
<a href="mailto:Development@qt-project.org">Development@qt-project.org</a><br>
<a href="http://lists.qt-project.org/mailman/listinfo/development" rel="noreferrer" target="_blank">http://lists.qt-project.org/<wbr>mailman/listinfo/development</a><br>
</font></span></blockquote></div><br></div></div>