1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5namespace bs
6{
7 /** @addtogroup General
8 * @{
9 */
10
11 /** Generates a new hash for the provided type using the default standard hasher and combines it with a previous hash. */
12 template <class T>
13 void bs_hash_combine(std::size_t& seed, const T& v)
14 {
15 using HashType = typename std::conditional<std::is_enum<T>::value, EnumClassHash, std::hash<T>>::type;
16
17 HashType hasher;
18 seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
19 }
20
21 /** Generates a hash for the provided type. Type must have a std::hash specialization. */
22 template <class T>
23 size_t bs_hash(const T& v)
24 {
25 using HashType = typename std::conditional<std::is_enum<T>::value, EnumClassHash, std::hash<T>>::type;
26
27 HashType hasher;
28 return hasher(v);
29 }
30
31 /** Generates an MD5 hash string for the provided source string. */
32 String BS_UTILITY_EXPORT md5(const WString& source);
33
34 /** Generates an MD5 hash string for the provided source string. */
35 String BS_UTILITY_EXPORT md5(const String& source);
36
37 /** Sets contents of a struct to zero. */
38 template<class T>
39 void bs_zero_out(T& s)
40 {
41 std::memset(&s, 0, sizeof(T));
42 }
43
44 /** Sets contents of a static array to zero. */
45 template<class T, size_t N>
46 void bs_zero_out(T(&arr)[N])
47 {
48 std::memset(arr, 0, sizeof(T) * N);
49 }
50
51 /** Sets contents of a block of memory to zero. */
52 template<class T>
53 void bs_zero_out(T* arr, size_t count)
54 {
55 assert(arr != nullptr);
56 std::memset(arr, 0, sizeof(T) * count);
57 }
58
59 /** Copies the contents of one array to another. Automatically accounts for array element size. */
60 template<class T, size_t N>
61 void bs_copy(T(&dst)[N], T(&src)[N], size_t count)
62 {
63 std::memcpy(dst, src, sizeof(T) * count);
64 }
65
66 /** Copies the contents of one array to another. Automatically accounts for array element size. */
67 template<class T>
68 void bs_copy(T* dst, T* src, size_t count)
69 {
70 std::memcpy(dst, src, sizeof(T) * count);
71 }
72
73 /** Returns the size of the provided static array. */
74 template <class T, std::size_t N>
75 constexpr size_t bs_size(const T (&array)[N])
76 {
77 return N;
78 }
79
80 /**
81 * Erases the provided element from the container, but first swaps the element so its located at the end of the
82 * container, making the erase operation cheaper at the cost of an extra move operation. Doesn't preserve ordering
83 * within the element. Returns true if a swap occurred, or false if the element was already at the end of the container.
84 */
85 template <class T, class A = StdAlloc<T>>
86 bool bs_swap_and_erase(Vector<T, A>& container, const typename Vector<T, A>::iterator iter)
87 {
88 assert(!container.empty());
89
90 auto iterLast = container.end() - 1;
91
92 bool swapped = false;
93 if(iter != iterLast)
94 {
95 std::swap(*iter, *iterLast);
96 swapped = true;
97 }
98
99 container.pop_back();
100 return swapped;
101 }
102
103 /** @} */
104}
105