common.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #pragma once
  2. #include <cmath>
  3. #include <cstring>
  4. #include <ctime>
  5. #include <stdexcept>
  6. #include <vector>
  7. #include <string>
  8. #include <chrono>
  9. #include <string_view>
  10. #include <memory>
  11. #include <iostream>
  12. #include <map>
  13. #include <set>
  14. #include <algorithm>
  15. #include <variant>
  16. #include <type_traits>
  17. #include <deque>
  18. #include <typeindex>
  19. #include <initializer_list>
  20. #define PK_VERSION "1.5.0"
  21. #include "config.h"
  22. #include "export.h"
  23. #include "_generated.h"
  24. #ifdef min
  25. #undef min
  26. #endif
  27. #ifdef max
  28. #undef max
  29. #endif
  30. /*******************************************************************************/
  31. #if PK_ENABLE_STD_FUNCTION
  32. #include <functional>
  33. #endif
  34. /*******************************************************************************/
  35. #if PK_ENABLE_THREAD
  36. #define PK_THREAD_LOCAL thread_local
  37. #include <mutex>
  38. struct GIL {
  39. inline static std::mutex _mutex;
  40. explicit GIL() { _mutex.lock(); }
  41. ~GIL() { _mutex.unlock(); }
  42. };
  43. #define PK_GLOBAL_SCOPE_LOCK() GIL _lock;
  44. #else
  45. #define PK_THREAD_LOCAL
  46. #define PK_GLOBAL_SCOPE_LOCK()
  47. #endif
  48. /*******************************************************************************/
  49. #define PK_UNUSED(x) (void)(x)
  50. #define PK_LOCAL_STATIC static
  51. namespace pkpy{
  52. namespace std = ::std;
  53. template <size_t T>
  54. struct NumberTraits;
  55. template <>
  56. struct NumberTraits<4> {
  57. using int_t = int32_t;
  58. static constexpr int_t kMaxSmallInt = (1 << 28) - 1;
  59. static constexpr int_t kMinSmallInt = 0;
  60. };
  61. template <>
  62. struct NumberTraits<8> {
  63. using int_t = int64_t;
  64. static constexpr int_t kMaxSmallInt = (1ll << 60) - 1;
  65. static constexpr int_t kMinSmallInt = 0;
  66. };
  67. using Number = NumberTraits<sizeof(void*)>;
  68. using i64 = int64_t; // always 64-bit
  69. using f64 = double; // always 64-bit
  70. static_assert(sizeof(i64) == 8);
  71. struct Dummy { }; // for special objects: True, False, None, Ellipsis, etc.
  72. struct DummyInstance { };
  73. struct DummyModule { };
  74. struct NoReturn { };
  75. struct Discarded { };
  76. struct Type {
  77. int16_t index;
  78. constexpr Type(): index(0) {}
  79. explicit constexpr Type(int index): index(index) {}
  80. bool operator==(Type other) const { return this->index == other.index; }
  81. bool operator!=(Type other) const { return this->index != other.index; }
  82. constexpr operator int() const { return index; }
  83. };
  84. #define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
  85. #define PK_VAR_LAMBDA(x) ([](VM* vm, ArgsView args) { return VAR(x); })
  86. #define PK_ACTION(x) ([](VM* vm, ArgsView args) { x; return vm->None; })
  87. #define PK_REGION(name) 1
  88. #ifdef POCKETPY_H
  89. #define PK_FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!");
  90. #else
  91. #define PK_FATAL_ERROR() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " FATAL_ERROR()!");
  92. #endif
  93. #define PK_ASSERT(x) if(!(x)) PK_FATAL_ERROR();
  94. #if PK_DEBUG_EXTRA_CHECK
  95. #define PK_DEBUG_ASSERT(x) if(!(x)) PK_FATAL_ERROR();
  96. #else
  97. #define PK_DEBUG_ASSERT(x)
  98. #endif
  99. // is_pod_v<> for c++17 and c++20
  100. template<typename T>
  101. inline constexpr bool is_pod_v = std::is_trivially_copyable_v<T> && std::is_standard_layout_v<T>;
  102. #define PK_ALWAYS_PASS_BY_POINTER(T) \
  103. T(const T&) = delete; \
  104. T& operator=(const T&) = delete; \
  105. T(T&&) = delete; \
  106. T& operator=(T&&) = delete;
  107. inline const char* kPlatformStrings[] = {
  108. "win32", // 0
  109. "emscripten", // 1
  110. "ios", // 2
  111. "darwin", // 3
  112. "android", // 4
  113. "linux", // 5
  114. "unknown" // 6
  115. };
  116. #define PK_SLICE_LOOP(i, start, stop, step) for(int i=start; step>0?i<stop:i>stop; i+=step)
  117. template<typename T>
  118. inline constexpr bool is_integral_v = std::is_same_v<T, char>
  119. || std::is_same_v<T, short>
  120. || std::is_same_v<T, int>
  121. || std::is_same_v<T, long>
  122. || std::is_same_v<T, long long>
  123. || std::is_same_v<T, unsigned char>
  124. || std::is_same_v<T, unsigned short>
  125. || std::is_same_v<T, unsigned int>
  126. || std::is_same_v<T, unsigned long>
  127. || std::is_same_v<T, unsigned long long>
  128. || std::is_same_v<T, signed char>; // for imgui
  129. template<typename T>
  130. inline constexpr bool is_floating_point_v = std::is_same_v<T, float> || std::is_same_v<T, double>;
  131. inline const char* PK_HEX_TABLE = "0123456789abcdef";
  132. struct PyObject;
  133. // using PyVar = PyObject *;
  134. struct PyVar final{
  135. Type type;
  136. bool is_sso;
  137. uint8_t flags;
  138. char _bytes[12];
  139. // uninitialized
  140. PyVar() = default;
  141. // zero initialized
  142. PyVar(std::nullptr_t): type(), is_sso(false), flags(0), _bytes{0} { }
  143. // PyObject* initialized (is_sso = false)
  144. PyVar(Type type, PyObject* p): type(type), is_sso(false), flags(0) {
  145. as<PyObject*>() = p;
  146. }
  147. // SSO initialized (is_sso = true)
  148. template<typename T>
  149. PyVar(Type type, T value): type(type), is_sso(true), flags(0) {
  150. static_assert(sizeof(T) <= sizeof(_bytes), "SSO size exceeded");
  151. as<T>() = value;
  152. }
  153. template<typename T>
  154. T& as() const {
  155. static_assert(!std::is_reference_v<T>);
  156. return *(T*)_bytes;
  157. }
  158. explicit operator bool() const { return (bool)type; }
  159. bool operator==(const PyVar& other) const {
  160. return memcmp(this, &other, sizeof(PyVar)) == 0;
  161. }
  162. bool operator!=(const PyVar& other) const {
  163. return memcmp(this, &other, sizeof(PyVar)) != 0;
  164. }
  165. bool operator==(std::nullptr_t) const { return !(bool)type; }
  166. bool operator!=(std::nullptr_t) const { return (bool)type; }
  167. PyObject* get() const {
  168. PK_DEBUG_ASSERT(!is_sso)
  169. return as<PyObject*>();
  170. }
  171. PyObject* operator->() const {
  172. PK_DEBUG_ASSERT(!is_sso)
  173. return as<PyObject*>();
  174. }
  175. i64 hash() const { return as<i64>(); }
  176. };
  177. static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>);
  178. // by default, only `int` and `float` enable SSO
  179. // users can specialize this template to enable SSO for other types
  180. // SSO types cannot have instance dict
  181. template<typename T>
  182. inline constexpr bool is_sso_v = is_integral_v<T> || is_floating_point_v<T>;
  183. } // namespace pkpy
  184. // specialize std::less for PyVar
  185. namespace std {
  186. template<>
  187. struct less<pkpy::PyVar> {
  188. bool operator()(const pkpy::PyVar& lhs, const pkpy::PyVar& rhs) const {
  189. return memcmp(&lhs, &rhs, sizeof(pkpy::PyVar)) < 0;
  190. }
  191. };
  192. }