On 08/01/20 18:47 -0500, David Malcolm wrote:
On Wed, 2019-12-04 at 10:59 -0700, Martin Sebor wrote:
On 11/15/19 6:23 PM, David Malcolm wrote:
> This patch adds an ordered_hash_map template, which is similar to
> hash_map, but preserves insertion order.
>
> gcc/ChangeLog:
>    * Makefile.in (OBJS): Add ordered-hash-map-tests.o.
>    * ordered-hash-map-tests.cc: New file.
>    * ordered-hash-map.h: New file.
>    * selftest-run-tests.c (selftest::run_tests): Call
>    selftest::ordered_hash_map_tests_cc_tests.
>    * selftest.h (selftest::ordered_hash_map_tests_cc_tests): New
>    decl.
> ---
>   gcc/Makefile.in               |   1 +
>   gcc/ordered-hash-map-tests.cc | 247
> ++++++++++++++++++++++++++++++++++++++++++
>   gcc/ordered-hash-map.h        | 184
> +++++++++++++++++++++++++++++++
>   gcc/selftest-run-tests.c      |   1 +
>   gcc/selftest.h                |   1 +
>   5 files changed, 434 insertions(+)
>   create mode 100644 gcc/ordered-hash-map-tests.cc
>   create mode 100644 gcc/ordered-hash-map.h
>

[...]

The container defines a copy-constructor but no copy assignment.
Is it safely assignable? (I don't think auto_vec is safely copyable
or assignable due to PR 90904.  It looks like the copy ctor works
around it below.)

It's not safely assignable; I don't believe I'm using that (I am using
the copy ctor).

I can make it private or similar to ensure it's not used.

Yes, if the compiler-generated assignment isn't safe, please declare
(but don't define) a private assignment operator, to suppress the
compiler-generated one.

I don't think I've made use of the hash_map copy ctor or copy
assignment but if it's anything like other GCC containers I'd
worry about it not doing the right thing, especially for non-
PODs.  I spent too much time chasing down miscompilations and
other problems due to bugs (or design limitations) in these
classes.

I'd far prefer to see us use libstdc++ containers in new code
than introduce new ones of our own.  They are better designed
and much better tested than these.  (I realize we're still
hampered by targeting C++ 98.)

Martin

[CCing Jonathan for libstdc++ expertise]

Is there such a container in libstdc++?


This patch implements a map that preserves insertion order when
iterating, without requiring the Key type to be comparable.

As far as I can tell, std::map instead is a map that requires the Key
type to be comparable,

Right.

and uses that to implement a red-black tree
(rather than via hashing),

Right.

and doesn't preserve insertion ordering.

std::map has unique keys anyway, so insertion order is irrelevant.
Iteration is done by key order.

std::multimap is the non-unique version, and preserves insertion order
for equivalent keys, but only since C++11. Before that it was
unspecified whether or not a duplicate key was inserted after existing
elements with equivalent keys.

I use this ordered_hash_map class later in various places in the
analyzer patch kit to ensure more deterministic results, so that
results aren't affected by hash values of possibly-changing pointer
values.

Nothing in the standard library provides that functionality out of the
box. The C++11 hash containers don't preserve order at all, even
equivalent elements can be reordered when insertion triggers
rehashing.

You could build something using a sequence container (vector, deque or
list) that preserves a stable order according to insertion order, and
then manually maintain a separate index of hash values used for
lookup. That might not make things any simpler (I haven't looked at
your actual patch).


Reply via email to