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 | |
5 | namespace 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 | |