BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_hash.h
Go to the documentation of this file.
1/// @file bslstl_hash.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_hash.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_HASH
9#define INCLUDED_BSLSTL_HASH
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_hash bslstl_hash
15/// @brief Provide a namespace for hash functions.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_hash
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_hash-purpose"> Purpose</a>
25/// * <a href="#bslstl_hash-classes"> Classes </a>
26/// * <a href="#bslstl_hash-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_hash-description"> Description </a>
28/// * <a href="#bslstl_hash-standard-hash-function"> Standard Hash Function </a>
29/// * <a href="#bslstl_hash-usage"> Usage </a>
30/// * <a href="#bslstl_hash-example-1-creating-and-using-a-hash-cross-reference"> Example 1: Creating and Using a Hash Cross Reference </a>
31/// * <a href="#bslstl_hash-example-2-using-hashappend-from-bslh-with-hashcrossreference"> Example 2: Using hashAppend from bslh with HashCrossReference </a>
32///
33/// # Purpose {#bslstl_hash-purpose}
34/// Provide a namespace for hash functions.
35///
36/// # Classes {#bslstl_hash-classes}
37///
38/// - bsl::hash: hash function for fundamental types
39///
40/// # Canonical Header {#bslstl_hash-canonical-header}
41/// bsl_functional.h
42///
43/// @see package bos+stdhdrs in the bos package group
44///
45/// # Description {#bslstl_hash-description}
46/// This component provides a template unary functor, `bsl::hash`,
47/// implementing the `std::hash` functor. `bsl::hash` applies a C++ standard
48/// compliant, implementation defined, hash function to fundamental types
49/// returning the result of such application.
50///
51/// ## Standard Hash Function {#bslstl_hash-standard-hash-function}
52///
53///
54/// According to the C++ standard the requirements of a standard hash function
55/// `h` are:
56///
57/// 1. Return a `size_t` value between 0 and
58/// `numeric_limits<std::size_t>::max()`.
59/// 2. The value returned must depend only on the argument `k`. For multiple
60/// evaluations with the same argument `k`, the value returned must be
61/// always the same.
62/// 3. The function should not modify its argument.
63///
64/// ## Usage {#bslstl_hash-usage}
65///
66///
67/// This section illustrates intended usage of this component.
68///
69/// ### Example 1: Creating and Using a Hash Cross Reference {#bslstl_hash-example-1-creating-and-using-a-hash-cross-reference}
70///
71///
72/// Suppose we already have an array of unique values of type `TYPE`, for which
73/// `operator==` is defined, and we want to be able to quickly look up whether
74/// an element is in the array, without exhaustively applying `operator==` to
75/// all the elements in sequence. The array itself is guaranteed not to change
76/// for the duration of our interest in it.
77///
78/// The problem is much simpler than building a general-purpose hash table,
79/// because we know how many elements our cross reference will contain in
80/// advance, so we will never have to dynamically grow the number of `buckets`.
81/// We do not need to copy the values into our own area, so we don't have to
82/// create storage for them, or require that a copy constructor or destructor be
83/// available. We only require that they have a transitive, symmetric
84/// equivalence operation `bool operator==` and that a hash function be
85/// provided.
86///
87/// We will need a hash function -- the hash function is a function that will
88/// take as input an object of the type stored in our array, and yield a
89/// `size_t` value that will be very randomized. Ideally, the slightest change
90/// in the value of the `TYPE` object will result in a large change in the value
91/// returned by the hash function. In a good hash function, typically half the
92/// bits of the return value will change for a 1-bit change in the hashed value.
93/// We then use the result of the hash function to index into our array of
94/// `buckets`. Each `bucket` is simply a pointer to a value in our original
95/// array of `TYPE` objects. We will resolve hash collisions in our array
96/// through `linear probing`, where we will search consecutive buckets following
97/// the bucket where the collision occurred, testing occupied buckets for
98/// equality with the value we are searching on, and concluding that the value
99/// is not in the table if we encounter an empty bucket before we encounter one
100/// referring to an equal element.
101///
102/// An important quality of the hash function is that if two values are
103/// equivalent, they must yield the same hash value.
104///
105/// First, we define our `HashCrossReference` template class, with the two type
106/// parameters `TYPE` (the type being referenced) and `HASHER`, which defaults
107/// to `bsl::hash<TYPE>`. For common types of `TYPE` such as `int`, a
108/// specialization of `bsl::hash` is already defined:
109/// @code
110/// /// This table leverages a hash table to provide a fast lookup of an
111/// /// external, non-owned, array of values of configurable type.
112/// ///
113/// /// The only requirement for `TYPE` is that it have a transitive,
114/// /// symmetric `operator==` function. There is no requirement that it
115/// /// have any kind of creator defined.
116/// ///
117/// /// The `HASHER` template parameter type must be a functor with a
118/// /// function of the following signature:
119/// /// ```
120/// /// size_t operator()(const TYPE) const; or
121/// /// size_t operator()(const TYPE&) const; or
122/// /// ```
123/// /// and `HASHER` must have a publicly available default constructor and
124/// /// destructor.
125/// template <class TYPE, class HASHER = bsl::hash<TYPE> >
126/// class HashCrossReference {
127///
128/// // DATA
129/// const TYPE *d_values; // Array of values table is to
130/// // cross-reference. Held, not
131/// // owned.
132/// size_t d_numValues; // Length of 'd_values'.
133/// const TYPE **d_bucketArray; // Contains pointers into
134/// // 'd_values'.
135/// size_t d_bucketArrayMask; // Will always be '2^N - 1'.
136/// HASHER d_hasher;
137/// bool d_valid; // Object was properly
138/// // initialized.
139/// bslma::Allocator *d_allocator_p; // Held, not owned.
140///
141/// private:
142/// // PRIVATE ACCESSORS
143///
144/// /// Look up the specified `value`, having hash value `hashValue`,
145/// /// and return its index in `d_bucketArray` stored in the specified
146/// /// `index`. If not found, return the vacant entry in
147/// /// `d_bucketArray` where it should be inserted. Return `true` if
148/// /// `value` is found and `false` otherwise.
149/// bool lookup(size_t *index,
150/// const TYPE& value,
151/// size_t hashValue) const
152/// {
153/// const TYPE *ptr;
154/// for (*index = hashValue & d_bucketArrayMask;
155/// static_cast<bool>(ptr = d_bucketArray[*index]);
156/// *index = (*index + 1) & d_bucketArrayMask) {
157/// if (value == *ptr) {
158/// return true; // RETURN
159/// }
160/// }
161/// // value was not found in table
162///
163/// return false;
164/// }
165///
166/// private:
167/// // NOT IMPLEMENTED
168/// HashCrossReference(const HashCrossReference&);
169/// HashCrossReference& operator=(const HashCrossReference&);
170///
171/// public:
172/// // CREATORS
173///
174/// /// Create a hash table refering to the specified `valuesArray`
175/// /// containing the specified `numValues` elements. Optionally
176/// /// specify `basicAllocator` or the default allocator will be used.
177/// HashCrossReference(const TYPE *valuesArray,
178/// size_t numValues,
179/// bslma::Allocator *basicAllocator = 0)
180/// : d_values(valuesArray)
181/// , d_numValues(numValues)
182/// , d_hasher()
183/// , d_valid(true)
184/// , d_allocator_p(bslma::Default::allocator(allocator))
185/// {
186/// size_t bucketArrayLength = 4;
187/// while (bucketArrayLength < numValues * 4) {
188/// bucketArrayLength *= 2;
189/// BSLS_ASSERT_OPT(bucketArrayLength);
190/// }
191/// d_bucketArrayMask = bucketArrayLength - 1;
192/// d_bucketArray = (const TYPE **) d_allocator_p->allocate(
193/// bucketArrayLength * sizeof(TYPE **));
194/// memset(d_bucketArray, 0, bucketArrayLength * sizeof(TYPE *));
195///
196/// for (unsigned i = 0; i < numValues; ++i) {
197/// const TYPE& value = d_values[i];
198///
199/// size_t idx;
200/// if (lookup(&idx, value, d_hasher(value))) {
201/// // Duplicate value. Fail.
202///
203/// printf("Error: entries %u and %u have the same value\n",
204/// i, unsigned(d_bucketArray[idx] - d_values));
205/// d_valid = false;
206///
207/// // don't return, continue reporting other redundant
208/// // entries.
209/// }
210/// else {
211/// d_bucketArray[idx] = &d_values[i];
212/// }
213/// }
214/// }
215///
216/// /// Free up memory used by this cross-reference.
217/// ~HashCrossReference()
218/// {
219/// d_allocator_p->deallocate(d_bucketArray);
220/// }
221///
222/// // ACCESSORS
223///
224/// /// Return 1 if the specified `value` is found in the cross
225/// /// reference and 0 otherwise.
226/// int count(const TYPE& value) const
227/// {
228/// BSLS_ASSERT_OPT(d_valid);
229///
230/// size_t idx;
231/// return lookup(&idx, value, d_hasher(value));
232/// }
233///
234/// /// Return `true` if this cross reference was successfully
235/// /// constructed and `false` otherwise.
236/// bool isValid() const
237/// {
238/// return d_valid;
239/// }
240/// };
241/// @endcode
242/// Then, In `main`, we will first use our cross-reference to cross-reference a
243/// collection of integer values. We define our array and take its length:
244/// @code
245/// const int ints[] = { 23, 42, 47, 56, 57, 61, 62, 63, 70, 72, 79 };
246/// enum { NUM_INTS = sizeof ints / sizeof *ints };
247/// @endcode
248/// Now, we create our cross-reference `hcri` and verify it constructed
249/// properly. Note that we don't specify the second template parameter `HASHER`
250/// and let it default to `bsl::hash<int>`, which is already defined by
251/// bslstl_hash:
252/// @code
253/// HashCrossReference<int> hcri(ints, NUM_INTS);
254/// assert(hcri.isValid());
255/// @endcode
256/// Finally, we use `hcri` to verify numbers that were and were not in the
257/// collection:
258/// @code
259/// assert(1 == hcri.count(23));
260/// assert(1 == hcri.count(42));
261/// assert(1 == hcri.count(47));
262/// assert(1 == hcri.count(56));
263/// assert(0 == hcri.count( 3));
264/// assert(0 == hcri.count(31));
265/// assert(0 == hcri.count(37));
266/// assert(0 == hcri.count(58));
267/// @endcode
268///
269/// ### Example 2: Using hashAppend from bslh with HashCrossReference {#bslstl_hash-example-2-using-hashappend-from-bslh-with-hashcrossreference}
270///
271///
272/// We want to specialize `bsl::hash` for a custom class. We can use the
273/// modular hashing system implemented in `bslh` rather than explicitly
274/// specializing `bsl::hash`. We will re-use the `HashCrossReference` template
275/// class defined in Example 1.
276///
277/// First, we declare `Point`, a class that allows us to identify a location on
278/// a two dimensional Cartesian plane.
279/// @code
280/// /// This class is a value-semantic type that represents a two-dimensional
281/// /// location on a Cartesian plane.
282/// class Point {
283///
284/// private:
285/// int d_x;
286/// int d_y;
287/// double d_distToOrigin; // This value will be accessed a lot, so we
288/// // cache it rather than recalculating every
289/// // time.
290///
291/// public:
292///
293/// /// Create a `Point` with the specified `x` and `y` coordinates
294/// Point (int x, int y);
295///
296/// /// Return the distance from the origin (0, 0) to this point.
297/// double distanceToOrigin();
298/// @endcode
299/// Then, we declare `operator==` as a friend so that we will be able to compare
300/// two points.
301/// @code
302/// friend bool operator==(const Point &left, const Point &right);
303///
304/// @endcode
305/// Next, we declare `hashAppend` as a friend so that we will be able hash a
306/// `Point`.
307/// @code
308/// /// Apply the specified `hashAlg` to the specified `point`.
309/// template <class HASH_ALGORITHM>
310/// friend
311/// void hashAppend(HASH_ALGORITHM &hashAlg, const Point &point);
312/// };
313///
314/// Point::Point(int x, int y)
315/// : d_x(x)
316/// , d_y(y)
317/// {
318/// d_distToOrigin = sqrt(static_cast<double>(d_x) * d_x +
319/// static_cast<double>(d_y) * d_y);
320/// }
321///
322/// double Point::distanceToOrigin()
323/// {
324/// return d_distToOrigin;
325/// }
326///
327/// @endcode
328/// Then, we define `operator==`. Notice how it only checks salient attributes
329/// - attributes that contribute to the value of the class. We ignore
330/// `d_distToOrigin` which is not required to determine equality.
331/// @code
332/// bool operator==(const Point &left, const Point &right)
333/// {
334/// return (left.d_x == right.d_x) && (left.d_y == right.d_y);
335/// }
336///
337/// @endcode
338/// Next, we define `hashAppend`. This method will allow any hashing algorithm
339/// to be applied to `Point`. This is the extent of the work that needs to be
340/// done by type creators. They do not need to implement any algorithms, they
341/// just need to call out the salient attributes (which have already been
342/// determined by `operator==`) by calling `hashAppend` on them.
343/// @code
344/// template <class HASH_ALGORITHM>
345/// void hashAppend(HASH_ALGORITHM &hashAlg, const Point &point)
346/// {
347/// using ::BloombergLP::bslh::hashAppend;
348/// hashAppend(hashAlg, point.d_x);
349/// hashAppend(hashAlg, point.d_y);
350/// }
351///
352/// @endcode
353/// Then, we declare another value-semantic type, `Box`, that has a `Point` as
354/// one of its salient attributes.
355/// @code
356/// /// This class is a value-semantic type that represents a box drawn on to
357/// /// a Cartesian plane.
358/// class Box {
359///
360/// private:
361/// Point d_position;
362/// int d_length;
363/// int d_width;
364///
365/// public:
366/// /// Create a box with the specified `length` and `width`, with its
367/// /// upper left corner at the specified `position`
368/// Box(Point position, int length, int width);
369///
370/// @endcode
371/// Next, we declare `operator==` and `hashAppend` as we did before.
372/// @code
373/// friend bool operator==(const Box &left, const Box &right);
374///
375/// /// Apply the specified `hashAlg` to the specified `box`.
376/// template <class HASH_ALGORITHM>
377/// friend
378/// void hashAppend(HASH_ALGORITHM &hashAlg, const Box &box);
379/// };
380///
381/// Box::Box(Point position, int length, int width) : d_position(position),
382/// d_length(length),
383/// d_width(width) { }
384///
385/// @endcode
386/// Then, we define `operator==`. This time all of the data members contribute
387/// to equality.
388/// @code
389/// bool operator==(const Box &left, const Box &right)
390/// {
391/// return (left.d_position == right.d_position) &&
392/// (left.d_length == right.d_length) &&
393/// (left.d_width == right.d_width);
394/// }
395///
396/// @endcode
397/// Next, we define `hashAppend` for `Box`. Notice how as well as calling
398/// `hashAppend` on fundamental types, we can also call it on our user-defined
399/// type `Point`. Calling `hashAppend` on `Point` will propagate the hashing
400/// algorithm functor `hashAlg` down to the fundamental types that make up
401/// `Point`, and those types will then be passed into the algorithm functor.
402/// @code
403/// template <class HASH_ALGORITHM>
404/// void hashAppend(HASH_ALGORITHM &hashAlg, const Box &box)
405/// {
406/// hashAppend(hashAlg, box.d_position);
407/// hashAppend(hashAlg, box.d_length);
408/// hashAppend(hashAlg, box.d_width);
409/// }
410/// @endcode
411/// Then, we want to use our cross reference on a `Box`. We create an array of
412/// unique `Box`s and take its length:
413/// @code
414/// Box boxes[] = { Box(Point(0, 0), 2, 3),
415/// Box(Point(1, 0), 1, 1),
416/// Box(Point(0, 1), 1, 5),
417/// Box(Point(1, 1), 5, 6),
418/// Box(Point(2, 1), 1, 13),
419/// Box(Point(0, 4), 3, 3),
420/// Box(Point(3, 2), 2, 17) };
421/// enum { NUM_BOXES = sizeof boxes / sizeof *boxes };
422/// @endcode
423/// Next, we create our cross-reference `hcrsts` and verify that it constructed
424/// properly. Note we don't pass a second parameter template argument and let
425/// `HASHER` default to `bsl::hash<TYPE>`. Since we have not specialized
426/// `bsl::hash` for `Box`, `bsl::hash<TYPE>` will attempt to use `bslh::hash<>`
427/// to hash `Box`.
428/// @code
429/// HashCrossReference<Box> hcrsts(boxes, NUM_BOXES);
430/// ASSERT(hcrsts.isValid());
431/// @endcode
432/// Now, we verify that each element in our array registers with count:
433/// @code
434/// for(int i = 0; i < NUM_BOXES; ++i) {
435/// ASSERT(1 == hcrsts.count(boxes[i]));
436/// }
437/// @endcode
438/// Finally, we verify that elements not in our original array are correctly
439/// identified as not being in the set:
440/// @code
441/// ASSERT(0 == hcrsts.count(Box(Point(3, 3), 3, 3)));
442/// ASSERT(0 == hcrsts.count(Box(Point(3, 2), 1, 0)));
443/// ASSERT(0 == hcrsts.count(Box(Point(1, 2), 3, 4)));
444/// ASSERT(0 == hcrsts.count(Box(Point(33, 23), 13, 3)));
445/// ASSERT(0 == hcrsts.count(Box(Point(30, 37), 34, 13)));
446/// @endcode
447/// @}
448/** @} */
449/** @} */
450
451/** @addtogroup bsl
452 * @{
453 */
454/** @addtogroup bslstl
455 * @{
456 */
457/** @addtogroup bslstl_hash
458 * @{
459 */
460
461#include <bslscm_version.h>
462
463#include <bslh_hash.h>
464
467#include <bslmf_assert.h>
468
471#include <bsls_platform.h>
472
473#include <cstddef> // for 'std::size_t'
474
475#define BSLSTL_HASH_DEPRECATED_CPP17 \
476 BSLS_DEPRECATE_FEATURE( \
477 "bsl", "deprecated_cpp17_standard_library_features", "do not use")
478
479namespace bsl {
480
481 // ==================
482 // class bslstl::hash
483 // ==================
484
485/// Empty base class for hashing. This class, and all explicit and partial
486/// specializations of this class, shall conform to the C++11 Hash
487/// Requirements (C++11 17.6.3.4, [hash.requirements]). Unless this
488/// template is explicitly specialized, it will use the default hash
489/// algorithm provided by `bslh::Hash<>` to supply hash values. In order to
490/// hash a user-defined type using `bsl::hash`, `bsl::hash` must be
491/// explicitly specialized for the type, or, preferably, `hashAppend` must
492/// be implemented for the type. For more details on `hashAppend` and
493/// `bslh::Hash` see the component @ref bslh_hash .
494template <class TYPE>
495struct hash : ::BloombergLP::bslh::Hash<> {
496
497 // PUBLIC ACCESSORS
498
499 /// Compute and return the hash of the specified `value`. This
500 /// implementation forwards to the call operator of the base class, but
501 /// with the parameter guaranteed to be of type `TYPE`.
502 std::size_t operator()(const TYPE &value) const;
503};
504
505// ============================================================================
506// SPECIALIZATIONS FOR FUNDAMENTAL TYPES
507// ============================================================================
508
509/// This class provides hashing functionality for constant key types, by
510/// delegating to the same function for non-constant key types.
511template <class BSLSTL_KEY>
512struct hash<const BSLSTL_KEY> : hash<BSLSTL_KEY> {
513};
514
515/// Specialization of `hash` for `bool` values.
516template <>
517struct hash<bool> {
518
519 // STANDARD TYPEDEFS
520
521 /// @deprecated This typedef is depreacted in C++17, for details see
522 /// https://isocpp.org/files/papers/p0005r4.html.
524 typedef bool argument_type;
525
526 /// @deprecated This typedef is depreacted in C++17, for details see
527 /// https://isocpp.org/files/papers/p0005r4.html.
529 typedef std::size_t result_type;
530
531 /// Create a `hash` object.
532 hash() = default;
533
534 /// Create a `hash` object.
535 /// \note Note that as `hash` is an empty (stateless)
536 /// type, this operation has no observable effect.
537 hash(const hash& original) = default;
538
539 /// Destroy this object.
540 ~hash() = default;
541
542 // MANIPULATORS
543
544 /// Assign to this object the value of the specified `rhs` object, and
545 /// return a reference providing modifiable access to this object.
546 ///
547 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
548 /// observable effect.
549 hash& operator=(const hash& rhs) = default;
550
551 // ACCESSORS
552
553 /// Return a hash value computed using the specified `x`.
554 std::size_t operator()(bool x) const;
555};
556
557/// Specialization of `hash` for `char` values.
558template <>
559struct hash<char> {
560
561 // STANDARD TYPEDEFS
562
563 /// @deprecated This typedef is depreacted in C++17, for details see
564 /// https://isocpp.org/files/papers/p0005r4.html.
566 typedef char argument_type;
567
568 /// @deprecated This typedef is depreacted in C++17, for details see
569 /// https://isocpp.org/files/papers/p0005r4.html.
571 typedef std::size_t result_type;
572
573 /// Create a `hash` object.
574 hash() = default;
575
576 /// Create a `hash` object.
577 /// \note Note that as `hash` is an empty (stateless)
578 /// type, this operation has no observable effect.
579 hash(const hash& original) = default;
580
581 /// Destroy this object.
582 ~hash() = default;
583
584 // MANIPULATORS
585
586 /// Assign to this object the value of the specified `rhs` object, and
587 /// return a reference providing modifiable access to this object.
588 ///
589 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
590 /// observable effect.
591 hash& operator=(const hash& rhs) = default;
592
593 // ACCESSORS
594
595 /// Return a hash value computed using the specified `x`.
596 std::size_t operator()(char x) const;
597};
598
599/// Specialization of `hash` for `signed` `char` values.
600template <>
601struct hash<signed char> {
602
603 // STANDARD TYPEDEFS
604
605 /// @deprecated This typedef is depreacted in C++17, for details see
606 /// https://isocpp.org/files/papers/p0005r4.html.
608 typedef signed char argument_type;
609
610 /// @deprecated This typedef is depreacted in C++17, for details see
611 /// https://isocpp.org/files/papers/p0005r4.html.
613 typedef std::size_t result_type;
614
615 /// Create a `hash` object.
616 hash() = default;
617
618 /// Create a `hash` object.
619 /// \note Note that as `hash` is an empty (stateless)
620 /// type, this operation has no observable effect.
621 hash(const hash& original) = default;
622
623 /// Destroy this object.
624 ~hash() = default;
625
626 // MANIPULATORS
627
628 /// Assign to this object the value of the specified `rhs` object, and
629 /// return a reference providing modifiable access to this object.
630 ///
631 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
632 /// observable effect.
633 hash& operator=(const hash& rhs) = default;
634
635 // ACCESSORS
636
637 /// Return a hash value computed using the specified `x`.
638 std::size_t operator()(signed char x) const;
639};
640
641/// Specialization of `hash` for `unsigned` `char` values.
642template <>
643struct hash<unsigned char> {
644
645 // STANDARD TYPEDEFS
646
647 /// @deprecated This typedef is depreacted in C++17, for details see
648 /// https://isocpp.org/files/papers/p0005r4.html.
650 typedef unsigned char argument_type;
651
652 /// @deprecated This typedef is depreacted in C++17, for details see
653 /// https://isocpp.org/files/papers/p0005r4.html.
655 typedef std::size_t result_type;
656
657 /// Create a `hash` object.
658 hash() = default;
659
660 /// Create a `hash` object.
661 /// \note Note that as `hash` is an empty (stateless)
662 /// type, this operation has no observable effect.
663 hash(const hash& original) = default;
664
665 /// Destroy this object.
666 ~hash() = default;
667
668 // MANIPULATORS
669
670 /// Assign to this object the value of the specified `rhs` object, and
671 /// return a reference providing modifiable access to this object.
672 ///
673 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
674 /// observable effect.
675 hash& operator=(const hash& rhs) = default;
676
677 // ACCESSORS
678
679 /// Return a hash value computed using the specified `x`.
680 std::size_t operator()(unsigned char x) const;
681};
682
683/// Specialization of `hash` for `wchar_t` values.
684template <>
685struct hash<wchar_t> {
686
687 // STANDARD TYPEDEFS
688
689 /// @deprecated This typedef is depreacted in C++17, for details see
690 /// https://isocpp.org/files/papers/p0005r4.html.
692 typedef wchar_t argument_type;
693
694 /// @deprecated This typedef is depreacted in C++17, for details see
695 /// https://isocpp.org/files/papers/p0005r4.html.
697 typedef std::size_t result_type;
698
699 /// Create a `hash` object.
700 hash() = default;
701
702 /// Create a `hash` object.
703 /// \note Note that as `hash` is an empty (stateless)
704 /// type, this operation has no observable effect.
705 hash(const hash& original) = default;
706
707 /// Destroy this object.
708 ~hash() = default;
709
710 // MANIPULATORS
711
712 /// Assign to this object the value of the specified `rhs` object, and
713 /// return a reference providing modifiable access to this object.
714 ///
715 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
716 /// observable effect.
717 hash& operator=(const hash& rhs) = default;
718
719 // ACCESSORS
720
721 /// Return a hash value computed using the specified `x`.
722 std::size_t operator()(wchar_t x) const;
723};
724
725/// Specialization of `hash` for `short` values.
726template <>
727struct hash<short> {
728
729 // STANDARD TYPEDEFS
730
731 /// @deprecated This typedef is depreacted in C++17, for details see
732 /// https://isocpp.org/files/papers/p0005r4.html.
734 typedef short argument_type;
735
736 /// @deprecated This typedef is depreacted in C++17, for details see
737 /// https://isocpp.org/files/papers/p0005r4.html.
739 typedef std::size_t result_type;
740
741 /// Create a `hash` object.
742 hash() = default;
743
744 /// Create a `hash` object.
745 /// \note Note that as `hash` is an empty (stateless)
746 /// type, this operation has no observable effect.
747 hash(const hash& original) = default;
748
749 /// Destroy this object.
750 ~hash() = default;
751
752 // MANIPULATORS
753
754 /// Assign to this object the value of the specified `rhs` object, and
755 /// return a reference providing modifiable access to this object.
756 ///
757 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
758 /// observable effect.
759 hash& operator=(const hash& rhs) = default;
760
761 // ACCESSORS
762
763 /// Return a hash value computed using the specified `x`.
764 std::size_t operator()(short x) const;
765};
766
767/// Specialization of `hash` for `unsigned` `short` values.
768template <>
769struct hash<unsigned short> {
770
771 // STANDARD TYPEDEFS
772
773 /// @deprecated This typedef is depreacted in C++17, for details see
774 /// https://isocpp.org/files/papers/p0005r4.html.
776 typedef unsigned short argument_type;
777
778 /// @deprecated This typedef is depreacted in C++17, for details see
779 /// https://isocpp.org/files/papers/p0005r4.html.
781 typedef std::size_t result_type;
782
783 /// Create a `hash` object.
784 hash() = default;
785
786 /// Create a `hash` object.
787 /// \note Note that as `hash` is an empty (stateless)
788 /// type, this operation has no observable effect.
789 hash(const hash& original) = default;
790
791 /// Destroy this object.
792 ~hash() = default;
793
794 // MANIPULATORS
795
796 /// Assign to this object the value of the specified `rhs` object, and
797 /// return a reference providing modifiable access to this object.
798 ///
799 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
800 /// observable effect.
801 hash& operator=(const hash& rhs) = default;
802
803 // ACCESSORS
804
805 /// Return a hash value computed using the specified `x`.
806 std::size_t operator()(unsigned short x) const;
807};
808
809/// Specialization of `hash` for `int` values.
810template <>
811struct hash<int> {
812
813 // STANDARD TYPEDEFS
814
815 /// @deprecated This typedef is depreacted in C++17, for details see
816 /// https://isocpp.org/files/papers/p0005r4.html.
818 typedef int argument_type;
819
820 /// @deprecated This typedef is depreacted in C++17, for details see
821 /// https://isocpp.org/files/papers/p0005r4.html.
823 typedef std::size_t result_type;
824
825 /// Create a `hash` object.
826 hash() = default;
827
828 /// Create a `hash` object.
829 /// \note Note that as `hash` is an empty (stateless)
830 /// type, this operation has no observable effect.
831 hash(const hash& original) = default;
832
833 /// Destroy this object.
834 ~hash() = default;
835
836 // MANIPULATORS
837
838 /// Assign to this object the value of the specified `rhs` object, and
839 /// return a reference providing modifiable access to this object.
840 ///
841 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
842 /// observable effect.
843 hash& operator=(const hash& rhs) = default;
844
845 // ACCESSORS
846
847 /// Return a hash value computed using the specified `x`.
848 std::size_t operator()(int x) const;
849};
850
851/// Specialization of `hash` for `unsigned` `int` values.
852template <>
853struct hash<unsigned int> {
854
855 // STANDARD TYPEDEFS
856
857 /// @deprecated This typedef is depreacted in C++17, for details see
858 /// https://isocpp.org/files/papers/p0005r4.html.
860 typedef unsigned int argument_type;
861
862 /// @deprecated This typedef is depreacted in C++17, for details see
863 /// https://isocpp.org/files/papers/p0005r4.html.
865 typedef std::size_t result_type;
866
867 /// Create a `hash` object.
868 hash() = default;
869
870 /// Create a `hash` object.
871 /// \note Note that as `hash` is an empty (stateless)
872 /// type, this operation has no observable effect.
873 hash(const hash& original) = default;
874
875 /// Destroy this object.
876 ~hash() = default;
877
878 // MANIPULATORS
879
880 /// Assign to this object the value of the specified `rhs` object, and
881 /// return a reference providing modifiable access to this object.
882 ///
883 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
884 /// observable effect.
885 hash& operator=(const hash& rhs) = default;
886
887 // ACCESSORS
888
889 /// Return a hash value computed using the specified `x`.
890 std::size_t operator()(unsigned int x) const;
891};
892
893/// Specialization of `hash` for `long` values.
894template <>
895struct hash<long> {
896
897 // STANDARD TYPEDEFS
898
899 /// @deprecated This typedef is depreacted in C++17, for details see
900 /// https://isocpp.org/files/papers/p0005r4.html.
902 typedef long argument_type;
903
904 /// @deprecated This typedef is depreacted in C++17, for details see
905 /// https://isocpp.org/files/papers/p0005r4.html.
907 typedef std::size_t result_type;
908
909 /// Create a `hash` object.
910 hash() = default;
911
912 /// Create a `hash` object.
913 /// \note Note that as `hash` is an empty (stateless)
914 /// type, this operation has no observable effect.
915 hash(const hash& original) = default;
916
917 /// Destroy this object.
918 ~hash() = default;
919
920 // MANIPULATORS
921
922 /// Assign to this object the value of the specified `rhs` object, and
923 /// return a reference providing modifiable access to this object.
924 ///
925 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
926 /// observable effect.
927 hash& operator=(const hash& rhs) = default;
928
929 // ACCESSORS
930
931 /// Return a hash value computed using the specified `x`.
932 std::size_t operator()(long x) const;
933};
934
935/// Specialization of `hash` for `unsigned` `long` values.
936template <>
937struct hash<unsigned long> {
938
939 // STANDARD TYPEDEFS
940
941 /// @deprecated This typedef is depreacted in C++17, for details see
942 /// https://isocpp.org/files/papers/p0005r4.html.
944 typedef unsigned long argument_type;
945
946 /// @deprecated This typedef is depreacted in C++17, for details see
947 /// https://isocpp.org/files/papers/p0005r4.html.
949 typedef std::size_t result_type;
950
951 /// Create a `hash` object.
952 hash() = default;
953
954 /// Create a `hash` object.
955 /// \note Note that as `hash` is an empty (stateless)
956 /// type, this operation has no observable effect.
957 hash(const hash& original) = default;
958
959 /// Destroy this object.
960 ~hash() = default;
961
962 // MANIPULATORS
963
964 /// Assign to this object the value of the specified `rhs` object, and
965 /// return a reference providing modifiable access to this object.
966 ///
967 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
968 /// observable effect.
969 hash& operator=(const hash& rhs) = default;
970
971 // ACCESSORS
972
973 /// Return a hash value computed using the specified `x`.
974 std::size_t operator()(unsigned long x) const;
975};
976
977/// Specialization of `hash` for `long long` values.
978template <>
979struct hash<long long> {
980
981 // STANDARD TYPEDEFS
982
983 /// @deprecated This typedef is depreacted in C++17, for details see
984 /// https://isocpp.org/files/papers/p0005r4.html.
986 typedef long long argument_type;
987
988 /// @deprecated This typedef is depreacted in C++17, for details see
989 /// https://isocpp.org/files/papers/p0005r4.html.
991 typedef std::size_t result_type;
992
993 /// Create a `hash` object.
994 hash() = default;
995
996 /// Create a `hash` object.
997 /// \note Note that as `hash` is an empty (stateless)
998 /// type, this operation has no observable effect.
999 hash(const hash& original) = default;
1000
1001 /// Destroy this object.
1002 ~hash() = default;
1003
1004 // MANIPULATORS
1005
1006 /// Assign to this object the value of the specified `rhs` object, and
1007 /// return a reference providing modifiable access to this object.
1008 ///
1009 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
1010 /// observable effect.
1011 hash& operator=(const hash& rhs) = default;
1012
1013 // ACCESSORS
1014
1015 /// Return a hash value computed using the specified `x`.
1016 std::size_t operator()(long long x) const;
1017};
1018
1019/// Specialization of `hash` for `unsigned` `long long` values.
1020template <>
1021struct hash<unsigned long long> {
1022
1023 // STANDARD TYPEDEFS
1024
1025 /// @deprecated This typedef is depreacted in C++17, for details see
1026 /// https://isocpp.org/files/papers/p0005r4.html.
1028 typedef unsigned long long argument_type;
1029
1030 /// @deprecated This typedef is depreacted in C++17, for details see
1031 /// https://isocpp.org/files/papers/p0005r4.html.
1033 typedef std::size_t result_type;
1034
1035 /// Create a `hash` object.
1036 hash() = default;
1037
1038 /// Create a `hash` object.
1039 /// \note Note that as `hash` is an empty (stateless)
1040 /// type, this operation has no observable effect.
1041 hash(const hash& original) = default;
1042
1043 /// Destroy this object.
1044 ~hash() = default;
1045
1046 // MANIPULATORS
1047
1048 /// Assign to this object the value of the specified `rhs` object, and
1049 /// return a reference providing modifiable access to this object.
1050 ///
1051 /// \note Note that as `hash` is an empty (stateless) type, this operation has no
1052 /// observable effect.
1053 hash& operator=(const hash& rhs) = default;
1054
1055 // ACCESSORS
1056
1057 /// Return a hash value computed using the specified `x`.
1058 std::size_t operator()(unsigned long long x) const;
1059};
1060
1061// ============================================================================
1062// TEMPLATE AND INLINE FUNCTION DEFINITIONS
1063// ============================================================================
1064
1065template <class TYPE>
1066inline
1067std::size_t hash<TYPE>::operator()(const TYPE& value) const
1068{
1069 return ::BloombergLP::bslh::Hash<>::operator()(value);
1070}
1071
1072inline
1073std::size_t hash<bool>::operator()(bool x) const
1074{
1075 return x;
1076}
1077
1078inline
1079std::size_t hash<char>::operator()(char x) const
1080{
1081 return x;
1082}
1083
1084inline
1085std::size_t hash<signed char>::operator()(signed char x) const
1086{
1087 return x;
1088}
1089
1090inline
1091std::size_t hash<unsigned char>::operator()(unsigned char x) const
1092{
1093 return x;
1094}
1095
1096inline
1097std::size_t hash<wchar_t>::operator()(wchar_t x) const
1098{
1099 return x;
1100}
1101
1102inline
1103std::size_t hash<short>::operator()(short x) const
1104{
1105 return x;
1106}
1107
1108inline
1109std::size_t hash<unsigned short>::operator()(unsigned short x) const
1110{
1111 return x;
1112}
1113
1114inline
1115std::size_t hash<int>::operator()(int x) const
1116{
1117 return x;
1118}
1119
1120inline
1121std::size_t hash<unsigned int>::operator()(unsigned int x) const
1122{
1123 return x;
1124}
1125
1126inline
1127std::size_t hash<long>::operator()(long x) const
1128{
1129 return x;
1130}
1131
1132inline
1133std::size_t hash<unsigned long>::operator()(unsigned long x) const
1134{
1135 return x;
1136}
1137
1138
1139#ifdef BSLS_PLATFORM_CPU_64_BIT
1140inline
1141std::size_t hash<long long>::operator()(long long x) const
1142{
1143 BSLMF_ASSERT(sizeof (long long) == sizeof (std::size_t));
1144 return x;
1145}
1146
1147inline
1148std::size_t hash<unsigned long long>::operator()(unsigned long long x) const
1149{
1150 BSLMF_ASSERT(sizeof (long long) == sizeof (std::size_t));
1151 return x;
1152}
1153
1154#else // BSLS_PLATFORM_CPU_32_BIT
1155
1156inline
1157std::size_t hash<long long>::operator()(long long x) const
1158{
1159 BSLMF_ASSERT(sizeof (long long) > sizeof (std::size_t));
1160
1161 // The mangling algorithm won't work unless these conditions hold:
1162
1163 BSLMF_ASSERT(sizeof (std::size_t) * 8 == 32);
1164 BSLMF_ASSERT(sizeof (long long) * 8 == 64);
1165
1166 // Return a simple mangling of the 64-bits of 'x' to generate a 32-bit hash
1167 // value (xor the high and low 32 bits together).
1168
1169 return static_cast<std::size_t>((x ^ (x >> 32)) & 0xFFFFFFFF);
1170}
1171
1172inline
1173std::size_t hash<unsigned long long>::operator()(unsigned long long x) const
1174{
1175 BSLMF_ASSERT(sizeof (long long) > sizeof (std::size_t));
1176
1177 // The mangling algorithm won't work unless these conditions hold:
1178
1179 BSLMF_ASSERT(sizeof (std::size_t) * 8 == 32);
1180 BSLMF_ASSERT(sizeof (unsigned long long) * 8 == 64);
1181
1182 // Return a simple mangling of the 64-bits of 'x' to generate a 32-bit hash
1183 // value (xor the high and low 32 bits together).
1184
1185 return static_cast<std::size_t>((x ^ (x >> 32)) & 0xFFFFFFFF);
1186}
1187#endif
1188
1189// ============================================================================
1190// TYPE TRAITS
1191// ============================================================================
1192
1193// Type traits for STL 'hash'
1194//: o 'bsl::hash<TYPE>' is trivially default constructible.
1195//: o 'bsl::hash<TYPE>' is trivially copyable.
1196//: o 'bsl::hash<TYPE>' is bitwise movable.
1197
1198template <class TYPE>
1202
1203template <class TYPE>
1206{};
1207
1208} // close namespace bsl
1209
1210#undef BSLSTL_HASH_DEPRECATED_CPP17
1211
1212#endif
1213
1214// ----------------------------------------------------------------------------
1215// Copyright 2013 Bloomberg Finance L.P.
1216//
1217// Licensed under the Apache License, Version 2.0 (the "License");
1218// you may not use this file except in compliance with the License.
1219// You may obtain a copy of the License at
1220//
1221// http://www.apache.org/licenses/LICENSE-2.0
1222//
1223// Unless required by applicable law or agreed to in writing, software
1224// distributed under the License is distributed on an "AS IS" BASIS,
1225// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1226// See the License for the specific language governing permissions and
1227// limitations under the License.
1228// ----------------------------- END-OF-FILE ----------------------------------
1229
1230/** @} */
1231/** @} */
1232/** @} */
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLSTL_HASH_DEPRECATED_CPP17
Definition bslstl_hash.h:475
Definition bdlat_valuetypefunctions.h:939
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
hash(const hash &original)=default
~hash()=default
Destroy this object.
hash & operator=(const hash &rhs)=default
hash()=default
Create a hash object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:529
BSLSTL_HASH_DEPRECATED_CPP17 typedef bool argument_type
Definition bslstl_hash.h:524
hash & operator=(const hash &rhs)=default
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:571
BSLSTL_HASH_DEPRECATED_CPP17 typedef char argument_type
Definition bslstl_hash.h:566
~hash()=default
Destroy this object.
hash()=default
Create a hash object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:823
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef int argument_type
Definition bslstl_hash.h:818
~hash()=default
Destroy this object.
hash()=default
Create a hash object.
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:907
hash & operator=(const hash &rhs)=default
hash()=default
Create a hash object.
~hash()=default
Destroy this object.
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef long argument_type
Definition bslstl_hash.h:902
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:991
BSLSTL_HASH_DEPRECATED_CPP17 typedef long long argument_type
Definition bslstl_hash.h:986
std::size_t operator()(long long x) const
Return a hash value computed using the specified x.
hash & operator=(const hash &rhs)=default
hash(const hash &original)=default
hash()=default
Create a hash object.
~hash()=default
Destroy this object.
~hash()=default
Destroy this object.
hash()=default
Create a hash object.
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:739
BSLSTL_HASH_DEPRECATED_CPP17 typedef short argument_type
Definition bslstl_hash.h:734
hash & operator=(const hash &rhs)=default
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef signed char argument_type
Definition bslstl_hash.h:608
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:613
std::size_t operator()(signed char x) const
Return a hash value computed using the specified x.
hash()=default
Create a hash object.
hash(const hash &original)=default
~hash()=default
Destroy this object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:655
~hash()=default
Destroy this object.
std::size_t operator()(unsigned char x) const
Return a hash value computed using the specified x.
hash()=default
Create a hash object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef unsigned char argument_type
Definition bslstl_hash.h:650
hash & operator=(const hash &rhs)=default
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:865
hash()=default
Create a hash object.
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef unsigned int argument_type
Definition bslstl_hash.h:860
~hash()=default
Destroy this object.
hash(const hash &original)=default
std::size_t operator()(unsigned int x) const
Return a hash value computed using the specified x.
std::size_t operator()(unsigned long x) const
Return a hash value computed using the specified x.
BSLSTL_HASH_DEPRECATED_CPP17 typedef unsigned long argument_type
Definition bslstl_hash.h:944
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:949
~hash()=default
Destroy this object.
hash(const hash &original)=default
hash()=default
Create a hash object.
std::size_t operator()(unsigned long long x) const
Return a hash value computed using the specified x.
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef unsigned long long argument_type
Definition bslstl_hash.h:1028
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:1033
~hash()=default
Destroy this object.
hash(const hash &original)=default
hash()=default
Create a hash object.
~hash()=default
Destroy this object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:781
hash()=default
Create a hash object.
hash & operator=(const hash &rhs)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef unsigned short argument_type
Definition bslstl_hash.h:776
hash(const hash &original)=default
std::size_t operator()(unsigned short x) const
Return a hash value computed using the specified x.
hash(const hash &original)=default
BSLSTL_HASH_DEPRECATED_CPP17 typedef std::size_t result_type
Definition bslstl_hash.h:697
hash & operator=(const hash &rhs)=default
hash()=default
Create a hash object.
BSLSTL_HASH_DEPRECATED_CPP17 typedef wchar_t argument_type
Definition bslstl_hash.h:692
~hash()=default
Destroy this object.
Definition bslstl_hash.h:495
std::size_t operator()(const TYPE &value) const
Definition bslstl_hash.h:1067
Definition bslmf_istriviallycopyable.h:324
Definition bslmf_istriviallydefaultconstructible.h:296