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