BsStdHeaders.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #ifdef __BORLANDC__
  5. #define __STD_ALGORITHM
  6. #endif
  7. #include <cassert>
  8. #include <cstdio>
  9. #include <cstdlib>
  10. #include <ctime>
  11. #include <cstring>
  12. #include <cstdarg>
  13. #include <cmath>
  14. #include <memory>
  15. // STL containers
  16. #include <vector>
  17. #include <stack>
  18. #include <map>
  19. #include <string>
  20. #include <set>
  21. #include <list>
  22. #include <deque>
  23. #include <queue>
  24. #include <bitset>
  25. #include <array>
  26. #include <unordered_map>
  27. #include <unordered_set>
  28. // STL algorithms & functions
  29. #include <algorithm>
  30. #include <functional>
  31. #include <limits>
  32. // C++ Stream stuff
  33. #include <fstream>
  34. #include <iostream>
  35. #include <iomanip>
  36. #include <sstream>
  37. extern "C" {
  38. # include <sys/types.h>
  39. # include <sys/stat.h>
  40. }
  41. #if BS_PLATFORM == BS_PLATFORM_WIN32
  42. # undef min
  43. # undef max
  44. # if !defined(NOMINMAX) && defined(_MSC_VER)
  45. # define NOMINMAX // required to stop windows.h messing up std::min
  46. # endif
  47. # if defined( __MINGW32__ )
  48. # include <unistd.h>
  49. # endif
  50. #endif
  51. #if BS_PLATFORM == BS_PLATFORM_LINUX
  52. extern "C" {
  53. # include <unistd.h>
  54. # include <dlfcn.h>
  55. }
  56. #endif
  57. #if BS_PLATFORM == BS_PLATFORM_OSX
  58. extern "C" {
  59. # include <unistd.h>
  60. # include <sys/param.h>
  61. # include <CoreFoundation/CoreFoundation.h>
  62. }
  63. #endif
  64. namespace bs
  65. {
  66. /**
  67. * Hash for enum types, to be used instead of std::hash<T> when T is an enum.
  68. *
  69. * Until C++14, std::hash<T> is not defined if T is a enum (see
  70. * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148). But
  71. * even with C++14, as of october 2016, std::hash for enums is not widely
  72. * implemented by compilers, so here when T is a enum, we use EnumClassHash
  73. * instead of std::hash. (For instance, in bs::hash_combine(), or
  74. * bs::UnorderedMap.)
  75. */
  76. struct EnumClassHash
  77. {
  78. template <typename T>
  79. std::size_t operator()(T t) const
  80. {
  81. return static_cast<std::size_t>(t);
  82. }
  83. };
  84. /** @addtogroup Containers
  85. * @{
  86. */
  87. /** Hasher that handles custom enums automatically. */
  88. template <typename Key>
  89. using HashType = typename std::conditional<std::is_enum<Key>::value, EnumClassHash, std::hash<Key>>::type;
  90. /** Double ended queue. Allows for fast insertion and removal at both its beggining and end. */
  91. template <typename T, typename A = StdAlloc<T>>
  92. using Deque = std::deque<T, A>;
  93. /** Dynamically sized array that stores element contigously. */
  94. template <typename T, typename A = StdAlloc<T>>
  95. using Vector = std::vector<T, A>;
  96. /** Container that supports constant time insertion and removal, but without fast random access to elements. */
  97. template <typename T, typename A = StdAlloc<T>>
  98. using List = std::list<T, A>;
  99. /** First-in, last-out data structure. */
  100. template <typename T, typename A = StdAlloc<T>>
  101. using Stack = std::stack<T, std::deque<T, A>>;
  102. /** First-in, first-out data structure. */
  103. template <typename T, typename A = StdAlloc<T>>
  104. using Queue = std::queue<T, std::deque<T, A>>;
  105. /** An associative container containing an ordered set of elements. */
  106. template <typename T, typename P = std::less<T>, typename A = StdAlloc<T>>
  107. using Set = std::set<T, P, A>;
  108. /** An associative container containing an ordered set of key-value pairs. */
  109. template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>>>
  110. using Map = std::map<K, V, P, A>;
  111. /** An associative container containing an ordered set of key-value pairs where multiple elements can have the same key. */
  112. template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>>>
  113. using MultiMap = std::multimap<K, V, P, A>;
  114. /** An associative container containing an unordered set of elements. Usually faster than Set for larger data sets. */
  115. template <typename T, typename H = HashType<T>, typename C = std::equal_to<T>, typename A = StdAlloc<T>>
  116. using UnorderedSet = std::unordered_set<T, H, C, A>;
  117. /** An associative container containing an ordered set of key-value pairs. Usually faster than Map for larger data sets. */
  118. template <typename K, typename V, typename H = HashType<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>>>
  119. using UnorderedMap = std::unordered_map<K, V, H, C, A>;
  120. /**
  121. * An associative container containing an ordered set of key-value pairs where multiple elements can have the same key.
  122. * Usually faster than MultiMap for larger data sets.
  123. */
  124. template <typename K, typename V, typename H = HashType<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>>>
  125. using UnorderedMultimap = std::unordered_multimap<K, V, H, C, A>;
  126. /** Equivalent to Vector, except it avoids any dynamic allocations until the number of elements exceeds @p Count. */
  127. template <typename T, int Count>
  128. using SmallVector = std::vector<T, StdAlloc<T>>; // TODO: Currently equivalent to Vector, need to implement the allocator
  129. /** @} */
  130. /** @addtogroup Memory
  131. * @{
  132. */
  133. /**
  134. * Smart pointer that retains shared ownership of an project through a pointer. The object is destroyed automatically
  135. * when the last shared pointer to the object is destroyed.
  136. */
  137. template <typename T>
  138. using SPtr = std::shared_ptr<T>;
  139. /**
  140. * Smart pointer that retains shared ownership of an project through a pointer. Reference to the object must be unique.
  141. * The object is destroyed automatically when the pointer to the object is destroyed.
  142. */
  143. template <typename T, typename Alloc = GenAlloc>
  144. using UPtr = std::unique_ptr<T, decltype(&bs_delete<T, Alloc>)>;
  145. /** Create a new shared pointer using a custom allocator category. */
  146. template<class Type, class AllocCategory, class... Args>
  147. SPtr<Type> bs_shared_ptr_new(Args &&... args)
  148. {
  149. return std::allocate_shared<Type>(StdAlloc<Type, AllocCategory>(), std::forward<Args>(args)...);
  150. }
  151. /** Create a new shared pointer using the default allocator category. */
  152. template<class Type, class... Args>
  153. SPtr<Type> bs_shared_ptr_new(Args &&... args)
  154. {
  155. return std::allocate_shared<Type>(StdAlloc<Type, GenAlloc>(), std::forward<Args>(args)...);
  156. }
  157. /**
  158. * Create a new shared pointer from a previously constructed object.
  159. * Pointer specific data will be allocated using the provided allocator category.
  160. */
  161. template<class Type, class MainAlloc = GenAlloc, class PtrDataAlloc = GenAlloc>
  162. SPtr<Type> bs_shared_ptr(Type* data)
  163. {
  164. return SPtr<Type>(data, &bs_delete<Type, MainAlloc>, StdAlloc<Type, PtrDataAlloc>());
  165. }
  166. /**
  167. * Create a new unique pointer from a previously constructed object.
  168. * Pointer specific data will be allocated using the provided allocator category.
  169. */
  170. template<class Type, class Alloc = GenAlloc>
  171. UPtr<Type, Alloc> bs_unique_ptr(Type* data)
  172. {
  173. return std::unique_ptr<Type, decltype(&bs_delete<Type, Alloc>)>(data, bs_delete<Type, Alloc>);
  174. }
  175. /** Create a new unique pointer using a custom allocator category. */
  176. template<class Type, class Alloc, class... Args>
  177. UPtr<Type> bs_unique_ptr_new(Args &&... args)
  178. {
  179. Type* rawPtr = bs_new<Type, Alloc>(std::forward<Args>(args)...);
  180. return bs_unique_ptr<Type, Alloc>(rawPtr);
  181. }
  182. /** Create a new unique pointer using the default allocator category. */
  183. template<class Type, class... Args>
  184. UPtr<Type> bs_unique_ptr_new(Args &&... args)
  185. {
  186. Type* rawPtr = bs_new<Type, GenAlloc>(std::forward<Args>(args)...);
  187. return bs_unique_ptr<Type, GenAlloc>(rawPtr);
  188. }
  189. /** @} */
  190. }