https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110357

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <[email protected]>:

https://gcc.gnu.org/g:1c9d93bfcd172c156fd0e94ea9990569bf46aeda

commit r16-5613-g1c9d93bfcd172c156fd0e94ea9990569bf46aeda
Author: Tomasz KamiÅski <[email protected]>
Date:   Wed Nov 19 10:29:18 2025 +0100

    libstdc++: Hashing support for chrono value classes [PR110357]

    This patch implements P2592R3 Hashing support for std::chrono value
classes.

    To avoid the know issues with current hashing of integer types (see
PR104945),
    we use chrono::__int_hash function that hash the bytes of representation,
    instead of hash<T>, as the later simply cast to value. Currently _Hash_impl
    it used, but we should consider replacing it (see PR55815) before C++26 ABI
    is made stable. The function is declared inside <chrono> header and chrono
    namespace, to make sure that only chrono components would be affected by
    such change. Finally, chrono::__int_hash is made variadic, to support
    combining hashes of multiple integers.

    To reduce the number of calls to hasher (defined out of line), the calendar
    types are packed into single unsigned integer value. This is done by
    chrono::__hash helper, that calls:
    * chrono::__as_int to cast the value of single component, to unsigned
integer
      with size matching the one used by internal representation: unsigned
short
      for year/weekday_indexed, and unsigned char in all other cases,
    * chrono::__pack_ints to pack integers (if more than one) into single
integer
      by performing bit shift operations,
    * chrono::__int_hash to hash the value produced by above.

    Hashing of duration, time_point, and zoned_time only hashes the value and
    ignores any difference in the period, i.e. hashes of nanoseconds(2) and
    seconds(2) are the same. This does not affect the usages inside unordered
    containers, as the arguments are converted to key type first. To address
    that period::num and period::den could be included in the hash, however
    such approach will not make hashes of equal durations (2000ms, 2s) equal,
    so they would remain unusable for precomputed hashes. In consequence,
    including period in hash, would only increase runtime cost, withou any
    clear benefits.

    Futhermore,  chrono::__int_hash is used when the duration representation
    is integral type, and for other types (floating point due special handling
    of +/-0.0 and user defined types) we delegate to hash specialization.
    This is automatically picked up by time_point, that delegates to hasher
    of duration. Similarly for leap_second that is specified to use integer
    durations, we simply hash representations of date() and value(). Finally
    zoned_time in addition to handling integer durations as described above,
    we also use __int_hash for const time_zone* (if used), as hash<T*> have
    similar problems as hash specialization for integers. This is limited
    only to _TimeZonePtr being const time_zone* (default), as user can define
    hash specializations for raw pointers to they zones.

    As accessing the representation for duration requires calling count()
    method that returns a copy of representation by value, the noexcept
    specification of the hasher needs to take into consideration copy
    constructor of duration. Similar reasoning applies for time_since_epoch
    for time_points, and get_sys_time, get_time_zone for zoned_time.
    For all this cases we use internal __is_nothrow_copy_hashable concept.

    Finally support for zoned_time is provided only for CXX11 string ABI,
    __cpp_lib_chrono feature test macro cannot be bumped if COW string are
used.
    To indicate presence of hasher for remaining types this patch also bumps
    the internal __glibcxx_chrono_cxx20 macro, and uses it as guard to new
    features.

            PR libstdc++/110357

    libstdc++-v3/ChangeLog:

            * include/bits/version.def (chrono, chrono_cxx20): Bump values.
            * include/bits/version.h: Regenerate.
            * include/std/chrono (__is_nothrow_copy_hashable)
            (chrono::__pack_ints, chrono::__as_int, chrono::__int_hash)
            (chrono::__hash): Define.
            (std::hash): Define partial specialization for duration,
time_point,
            and zoned_time, and full specializations for calendar types and
            leap_second.
            (std::__is_fast_hash): Define partial specializations for duration,
            time_point, zoned_time.
            * testsuite/std/time/hash.cc: New test.

    Reviewed-by: Jonathan Wakely <[email protected]>
    Co-authored-by: Giuseppe D'Angelo <[email protected]>
    Signed-off-by: Tomasz KamiÅski <[email protected]>
    Signed-off-by: Giuseppe D'Angelo <[email protected]>
  • [Bug libstdc++/110357] [C++26] ... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to