react-native-nitro-modules 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/NitroModules.podspec +1 -1
  2. package/README.md +210 -0
  3. package/android/CMakeLists.txt +1 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/cpp/JNIOnLoad.cpp +17 -0
  6. package/android/src/main/cpp/core/JHybridObject.cpp +8 -0
  7. package/android/src/main/cpp/core/JHybridObject.hpp +25 -0
  8. package/android/src/main/cpp/platform/ThreadUtils.cpp +35 -0
  9. package/android/src/main/cpp/registry/JHybridObjectInitializer.hpp +29 -0
  10. package/android/src/main/cpp/registry/JHybridObjectRegistry.cpp +35 -0
  11. package/android/src/main/cpp/registry/JHybridObjectRegistry.hpp +30 -0
  12. package/android/src/main/cpp/utils/JNISharedPtr.h +36 -0
  13. package/android/src/main/java/com/margelo/nitro/HybridObject.kt +61 -0
  14. package/android/src/main/java/com/margelo/nitro/HybridObjectInitializer.java +13 -0
  15. package/android/src/main/java/com/margelo/nitro/HybridObjectRegistry.java +30 -0
  16. package/android/src/main/java/com/margelo/nitro/NitroModulesPackage.java +26 -0
  17. package/cpp/core/HybridObject.hpp +23 -8
  18. package/cpp/core/PointerHolder.hpp +2 -1
  19. package/cpp/jsi/JSICache.hpp +6 -3
  20. package/cpp/jsi/JSIConverter.hpp +50 -39
  21. package/cpp/templates/CountTrailingOptionals.hpp +64 -0
  22. package/cpp/templates/FutureType.hpp +28 -0
  23. package/cpp/templates/IsHostObject.hpp +27 -0
  24. package/cpp/templates/IsInPack.hpp +21 -0
  25. package/cpp/templates/IsNativeState.hpp +27 -0
  26. package/cpp/threading/Dispatcher.hpp +2 -1
  27. package/cpp/utils/BorrowingReference+Owning.hpp +4 -2
  28. package/cpp/utils/BorrowingReference.hpp +5 -3
  29. package/cpp/utils/NitroHash.hpp +2 -1
  30. package/cpp/utils/NitroLogger.hpp +6 -3
  31. package/cpp/utils/OwningLock.hpp +4 -2
  32. package/cpp/utils/OwningReference.hpp +5 -4
  33. package/cpp/utils/TypeInfo.hpp +4 -2
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +8 -36
  36. package/cpp/utils/DoesClassExist.hpp +0 -23
  37. /package/cpp/{jsi → core}/ArrayBuffer.hpp +0 -0
@@ -23,9 +23,11 @@ using namespace facebook;
23
23
 
24
24
  static constexpr auto CACHE_PROP_NAME = "__nitroModulesJSICache";
25
25
 
26
- template <typename T> class JSICache;
26
+ template <typename T>
27
+ class JSICache;
27
28
 
28
- template <typename T> class JSICacheReference final {
29
+ template <typename T>
30
+ class JSICacheReference final {
29
31
  public:
30
32
  JSICacheReference() = delete;
31
33
  JSICacheReference(const JSICacheReference&) = delete;
@@ -70,7 +72,8 @@ private:
70
72
  * `jsi::Pointer`s are managed by a `jsi::Runtime`, and will be deleted if the `jsi::Runtime`
71
73
  * is deleted - even if there are still strong references to the `jsi::Pointer`.
72
74
  */
73
- template <typename T = jsi::Pointer> class JSICache final : public jsi::NativeState {
75
+ template <typename T = jsi::Pointer>
76
+ class JSICache final : public jsi::NativeState {
74
77
  public:
75
78
  explicit JSICache(jsi::Runtime* runtime) : _runtime(runtime) {}
76
79
 
@@ -11,7 +11,11 @@ class HybridObject;
11
11
  #include "AnyMap.hpp"
12
12
  #include "ArrayBuffer.hpp"
13
13
  #include "Dispatcher.hpp"
14
+ #include "FutureType.hpp"
14
15
  #include "HybridObject.hpp"
16
+ #include "IsHostObject.hpp"
17
+ #include "IsInPack.hpp"
18
+ #include "IsNativeState.hpp"
15
19
  #include "JSICache.hpp"
16
20
  #include "NitroHash.hpp"
17
21
  #include "Promise.hpp"
@@ -40,7 +44,8 @@ namespace margelo::nitro {
40
44
  using namespace facebook;
41
45
 
42
46
  // Unknown type (error)
43
- template <typename ArgType, typename Enable = void> struct JSIConverter final {
47
+ template <typename ArgType, typename Enable = void>
48
+ struct JSIConverter final {
44
49
  JSIConverter() = delete;
45
50
 
46
51
  static inline ArgType fromJSI(jsi::Runtime&, const jsi::Value&) {
@@ -53,11 +58,13 @@ template <typename ArgType, typename Enable = void> struct JSIConverter final {
53
58
  }
54
59
 
55
60
  private:
56
- template <typename> struct always_false : std::false_type {};
61
+ template <typename>
62
+ struct always_false : std::false_type {};
57
63
  };
58
64
 
59
65
  // int <> number
60
- template <> struct JSIConverter<int> {
66
+ template <>
67
+ struct JSIConverter<int> {
61
68
  static inline int fromJSI(jsi::Runtime&, const jsi::Value& arg) {
62
69
  return static_cast<int>(arg.asNumber());
63
70
  }
@@ -67,7 +74,8 @@ template <> struct JSIConverter<int> {
67
74
  };
68
75
 
69
76
  // std::monostate <> null
70
- template <> struct JSIConverter<std::monostate> {
77
+ template <>
78
+ struct JSIConverter<std::monostate> {
71
79
  static inline std::monostate fromJSI(jsi::Runtime&, const jsi::Value& arg) {
72
80
  return std::monostate();
73
81
  }
@@ -77,7 +85,8 @@ template <> struct JSIConverter<std::monostate> {
77
85
  };
78
86
 
79
87
  // double <> number
80
- template <> struct JSIConverter<double> {
88
+ template <>
89
+ struct JSIConverter<double> {
81
90
  static inline double fromJSI(jsi::Runtime&, const jsi::Value& arg) {
82
91
  return arg.asNumber();
83
92
  }
@@ -87,7 +96,8 @@ template <> struct JSIConverter<double> {
87
96
  };
88
97
 
89
98
  // float <> number
90
- template <> struct JSIConverter<float> {
99
+ template <>
100
+ struct JSIConverter<float> {
91
101
  static inline float fromJSI(jsi::Runtime&, const jsi::Value& arg) {
92
102
  return static_cast<float>(arg.asNumber());
93
103
  }
@@ -97,7 +107,8 @@ template <> struct JSIConverter<float> {
97
107
  };
98
108
 
99
109
  // int64_t <> BigInt
100
- template <> struct JSIConverter<int64_t> {
110
+ template <>
111
+ struct JSIConverter<int64_t> {
101
112
  static inline double fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
102
113
  return arg.asBigInt(runtime).asInt64(runtime);
103
114
  }
@@ -107,7 +118,8 @@ template <> struct JSIConverter<int64_t> {
107
118
  };
108
119
 
109
120
  // uint64_t <> BigInt
110
- template <> struct JSIConverter<uint64_t> {
121
+ template <>
122
+ struct JSIConverter<uint64_t> {
111
123
  static inline double fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
112
124
  return arg.asBigInt(runtime).asUint64(runtime);
113
125
  }
@@ -117,7 +129,8 @@ template <> struct JSIConverter<uint64_t> {
117
129
  };
118
130
 
119
131
  // bool <> boolean
120
- template <> struct JSIConverter<bool> {
132
+ template <>
133
+ struct JSIConverter<bool> {
121
134
  static inline bool fromJSI(jsi::Runtime&, const jsi::Value& arg) {
122
135
  return arg.asBool();
123
136
  }
@@ -127,7 +140,8 @@ template <> struct JSIConverter<bool> {
127
140
  };
128
141
 
129
142
  // std::string <> string
130
- template <> struct JSIConverter<std::string> {
143
+ template <>
144
+ struct JSIConverter<std::string> {
131
145
  static inline std::string fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
132
146
  return arg.asString(runtime).utf8(runtime);
133
147
  }
@@ -137,7 +151,8 @@ template <> struct JSIConverter<std::string> {
137
151
  };
138
152
 
139
153
  // std::optional<T> <> T | undefined
140
- template <typename TInner> struct JSIConverter<std::optional<TInner>> {
154
+ template <typename TInner>
155
+ struct JSIConverter<std::optional<TInner>> {
141
156
  static inline std::optional<TInner> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
142
157
  if (arg.isUndefined() || arg.isNull()) {
143
158
  return std::nullopt;
@@ -155,7 +170,8 @@ template <typename TInner> struct JSIConverter<std::optional<TInner>> {
155
170
  };
156
171
 
157
172
  // std::future<T> <> Promise<T>
158
- template <typename TResult> struct JSIConverter<std::future<TResult>> {
173
+ template <typename TResult>
174
+ struct JSIConverter<std::future<TResult>> {
159
175
  static inline std::future<TResult> fromJSI(jsi::Runtime&, const jsi::Value&) {
160
176
  throw std::runtime_error("Promise cannot be converted to a native type - it needs to be awaited first!");
161
177
  }
@@ -210,18 +226,11 @@ template <typename TResult> struct JSIConverter<std::future<TResult>> {
210
226
  }
211
227
  };
212
228
 
213
- template <typename T> struct future_traits {
214
- using type = void;
215
- };
216
- template <typename T> struct future_traits<std::future<T>> {
217
- using type = T;
218
- };
219
- template <typename T> using future_traits_t = typename future_traits<std::remove_reference_t<T>>::type;
220
-
221
229
  // [](Args...) -> T {} <> (Args...) => T
222
- template <typename ReturnType, typename... Args> struct JSIConverter<std::function<ReturnType(Args...)>> {
230
+ template <typename ReturnType, typename... Args>
231
+ struct JSIConverter<std::function<ReturnType(Args...)>> {
223
232
  // std::future<T> -> T
224
- using ResultingType = future_traits_t<ReturnType>;
233
+ using ResultingType = future_type_v<ReturnType>;
225
234
 
226
235
  static inline ResultingType callJSFunction(jsi::Runtime& runtime, const OwningReference<jsi::Function>& function, const Args&... args) {
227
236
  // Throw a lock on the OwningReference<T> so we can guarantee safe access (Hermes GC cannot delete it while `lock` is alive)
@@ -311,7 +320,8 @@ template <typename ReturnType, typename... Args> struct JSIConverter<std::functi
311
320
  };
312
321
 
313
322
  // std::vector<T> <> T[]
314
- template <typename ElementType> struct JSIConverter<std::vector<ElementType>> {
323
+ template <typename ElementType>
324
+ struct JSIConverter<std::vector<ElementType>> {
315
325
  static inline std::vector<ElementType> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
316
326
  jsi::Array array = arg.asObject(runtime).asArray(runtime);
317
327
  size_t length = array.size(runtime);
@@ -335,7 +345,8 @@ template <typename ElementType> struct JSIConverter<std::vector<ElementType>> {
335
345
  };
336
346
 
337
347
  // std::unordered_map<std::string, T> <> Record<string, T>
338
- template <typename ValueType> struct JSIConverter<std::unordered_map<std::string, ValueType>> {
348
+ template <typename ValueType>
349
+ struct JSIConverter<std::unordered_map<std::string, ValueType>> {
339
350
  static inline std::unordered_map<std::string, ValueType> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
340
351
  jsi::Object object = arg.asObject(runtime);
341
352
  jsi::Array propertyNames = object.getPropertyNames(runtime);
@@ -360,7 +371,9 @@ template <typename ValueType> struct JSIConverter<std::unordered_map<std::string
360
371
  }
361
372
  };
362
373
 
363
- template <typename... Types> struct JSIConverter<std::tuple<Types...>> {
374
+ // std::tuple<A, B, C> <> [A, B, C]
375
+ template <typename... Types>
376
+ struct JSIConverter<std::tuple<Types...>> {
364
377
  static inline std::tuple<Types...> fromJSI(jsi::Runtime& runtime, const jsi::Value& value) {
365
378
  jsi::Object object = value.asObject(runtime);
366
379
  jsi::Array array = object.asArray(runtime);
@@ -394,12 +407,9 @@ private:
394
407
  }
395
408
  };
396
409
 
397
- // Helper struct to check if a type is present in a parameter pack
398
- template <typename T, typename... Types> struct is_in_pack : std::disjunction<std::is_same<T, Types>...> {};
399
- template <typename T, typename... Types> inline constexpr bool is_in_pack_v = is_in_pack<T, Types...>::value;
400
-
401
410
  // std::variant<A, B, C> <> A | B | C
402
- template <typename... Types> struct JSIConverter<std::variant<Types...>> {
411
+ template <typename... Types>
412
+ struct JSIConverter<std::variant<Types...>> {
403
413
  static inline std::variant<Types...> fromJSI(jsi::Runtime& runtime, const jsi::Value& value) {
404
414
  if (value.isNull()) {
405
415
  if constexpr (is_in_pack_v<std::monostate, Types...>) {
@@ -464,7 +474,8 @@ private:
464
474
  };
465
475
 
466
476
  // AnyValue <> Record<K, V>
467
- template <> struct JSIConverter<AnyValue> {
477
+ template <>
478
+ struct JSIConverter<AnyValue> {
468
479
  static inline AnyValue fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
469
480
  return JSIConverter<AnyValue::variant>::fromJSI(runtime, arg);
470
481
  }
@@ -474,7 +485,8 @@ template <> struct JSIConverter<AnyValue> {
474
485
  };
475
486
 
476
487
  // AnyMap <> Record<K, V>
477
- template <> struct JSIConverter<std::shared_ptr<AnyMap>> {
488
+ template <>
489
+ struct JSIConverter<std::shared_ptr<AnyMap>> {
478
490
  static inline std::shared_ptr<AnyMap> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
479
491
  jsi::Object object = arg.asObject(runtime);
480
492
  jsi::Array propNames = object.getPropertyNames(runtime);
@@ -499,7 +511,8 @@ template <> struct JSIConverter<std::shared_ptr<AnyMap>> {
499
511
  };
500
512
 
501
513
  // MutableBuffer <> ArrayBuffer
502
- template <> struct JSIConverter<std::shared_ptr<jsi::MutableBuffer>> {
514
+ template <>
515
+ struct JSIConverter<std::shared_ptr<jsi::MutableBuffer>> {
503
516
  static inline std::shared_ptr<ArrayBuffer> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
504
517
  jsi::Object object = arg.asObject(runtime);
505
518
  if (!object.isArrayBuffer(runtime)) [[unlikely]] {
@@ -514,9 +527,8 @@ template <> struct JSIConverter<std::shared_ptr<jsi::MutableBuffer>> {
514
527
  };
515
528
 
516
529
  // HybridObject <> {}
517
- template <typename T> struct is_shared_ptr_to_host_object : std::false_type {};
518
- template <typename T> struct is_shared_ptr_to_host_object<std::shared_ptr<T>> : std::is_base_of<jsi::HostObject, T> {};
519
- template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_host_object<T>::value>> {
530
+ template <typename T>
531
+ struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_host_object_v<T>>> {
520
532
  using TPointee = typename T::element_type;
521
533
 
522
534
  static inline T fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
@@ -563,9 +575,8 @@ private:
563
575
  };
564
576
 
565
577
  // NativeState <> {}
566
- template <typename T> struct is_shared_ptr_to_native_state : std::false_type {};
567
- template <typename T> struct is_shared_ptr_to_native_state<std::shared_ptr<T>> : std::is_base_of<jsi::NativeState, T> {};
568
- template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_native_state<T>::value>> {
578
+ template <typename T>
579
+ struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_native_state_v<T>>> {
569
580
  using TPointee = typename T::element_type;
570
581
 
571
582
  static inline T fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
@@ -0,0 +1,64 @@
1
+ //
2
+ // CountTrailingOptionals.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 21.06.24.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <optional>
11
+ #include <type_traits>
12
+
13
+ namespace margelo::nitro {
14
+
15
+ // Helper template to check if a type is std::optional
16
+ template <typename T>
17
+ struct is_optional : std::false_type {};
18
+
19
+ template <typename T>
20
+ struct is_optional<std::optional<T>> : std::true_type {};
21
+
22
+ // Helper template to count trailing optionals
23
+ template <int N = 0, typename... Args>
24
+ struct count_trailing_optionals;
25
+
26
+ template <>
27
+ struct count_trailing_optionals<> {
28
+ static constexpr int value = 0;
29
+ };
30
+
31
+ template <int N, typename Current, typename... Rest>
32
+ struct count_trailing_optionals<N, Current, Rest...> {
33
+ static constexpr int count_trailing_optionals_impl() {
34
+ constexpr bool isOptional = is_optional<std::remove_cvref_t<Current>>::value;
35
+ if constexpr (sizeof...(Rest) == 0) {
36
+ // end of parameter pack!
37
+ if constexpr (isOptional) {
38
+ // last item is an optional, finally return the final number incremented by one.
39
+ return N + 1;
40
+ } else {
41
+ // last item is not an optional, so there are 0 trailing optionals.
42
+ return 0;
43
+ }
44
+ } else {
45
+ // recursively look into next T, either bump N by one or reset it to 0 if it's not an optional.
46
+ constexpr int newValue = isOptional ? N + 1 : 0;
47
+ return count_trailing_optionals<newValue, Rest...>::count_trailing_optionals_impl();
48
+ }
49
+ }
50
+
51
+ static constexpr int value = count_trailing_optionals_impl();
52
+ };
53
+
54
+ // Main template to count trailing optionals in Args... pack
55
+ template <typename... Args>
56
+ struct trailing_optionals_count {
57
+ static constexpr int value = count_trailing_optionals<0, Args...>::value;
58
+ };
59
+
60
+ // Helper alias
61
+ template <typename... Args>
62
+ constexpr int trailing_optionals_count_v = trailing_optionals_count<std::remove_cvref_t<Args>...>::value;
63
+
64
+ } // namespace margelo::nitro
@@ -0,0 +1,28 @@
1
+ //
2
+ // BorrowingReference.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 21.06.24.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <future>
11
+ #include <type_traits>
12
+
13
+ namespace margelo::nitro {
14
+
15
+ // Gets the `T` in `std::future<T>`.
16
+ template <typename T>
17
+ struct future_type {
18
+ using type = void;
19
+ };
20
+ template <typename T>
21
+ struct future_type<std::future<T>> {
22
+ using type = T;
23
+ };
24
+
25
+ template <typename T>
26
+ using future_type_v = typename future_type<std::remove_reference_t<T>>::type;
27
+
28
+ } // namespace margelo::nitro
@@ -0,0 +1,27 @@
1
+ //
2
+ // BorrowingReference.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 21.06.24.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <jsi/jsi.h>
11
+ #include <type_traits>
12
+
13
+ namespace margelo::nitro {
14
+
15
+ using namespace facebook;
16
+
17
+ // Returns whether the given type `T` is a `shared_ptr` to a `HostObject`
18
+ template <typename T>
19
+ struct is_shared_ptr_to_host_object : std::false_type {};
20
+
21
+ template <typename T>
22
+ struct is_shared_ptr_to_host_object<std::shared_ptr<T>> : std::is_base_of<jsi::HostObject, T> {};
23
+
24
+ template <typename T>
25
+ inline constexpr bool is_shared_ptr_to_host_object_v = is_shared_ptr_to_host_object<std::remove_reference_t<T>>::value;
26
+
27
+ } // namespace margelo::nitro
@@ -0,0 +1,21 @@
1
+ //
2
+ // BorrowingReference.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 21.06.24.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <type_traits>
11
+
12
+ namespace margelo::nitro {
13
+
14
+ // Returns whether the given type `T` is inside `Types...`
15
+ template <typename T, typename... Types>
16
+ struct is_in_pack : std::disjunction<std::is_same<T, Types>...> {};
17
+
18
+ template <typename T, typename... Types>
19
+ inline constexpr bool is_in_pack_v = is_in_pack<T, Types...>::value;
20
+
21
+ } // namespace margelo::nitro
@@ -0,0 +1,27 @@
1
+ //
2
+ // BorrowingReference.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 21.06.24.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <jsi/jsi.h>
11
+ #include <type_traits>
12
+
13
+ namespace margelo::nitro {
14
+
15
+ using namespace facebook;
16
+
17
+ // Returns whether the given type `T` is a `shared_ptr` to a `NativeStaet`
18
+ template <typename T>
19
+ struct is_shared_ptr_to_native_state : std::false_type {};
20
+
21
+ template <typename T>
22
+ struct is_shared_ptr_to_native_state<std::shared_ptr<T>> : std::is_base_of<jsi::NativeState, T> {};
23
+
24
+ template <typename T>
25
+ inline constexpr bool is_shared_ptr_to_native_state_v = is_shared_ptr_to_native_state<std::remove_reference_t<T>>::value;
26
+
27
+ } // namespace margelo::nitro
@@ -44,7 +44,8 @@ public:
44
44
  * Run the given function asynchronously on the Thread this Dispatcher is managing,
45
45
  * and return a future that will hold the result of the function.
46
46
  */
47
- template <typename T> std::future<T> runAsyncAwaitable(std::function<T()>&& function) {
47
+ template <typename T>
48
+ std::future<T> runAsyncAwaitable(std::function<T()>&& function) {
48
49
  // 1. Create Promise that can be shared between this and dispatcher thread
49
50
  auto promise = std::make_shared<std::promise<T>>();
50
51
  std::future<T> future = promise->get_future();
@@ -11,7 +11,8 @@
11
11
 
12
12
  namespace margelo::nitro {
13
13
 
14
- template <typename T> BorrowingReference<T>::BorrowingReference(const OwningReference<T>& ref) {
14
+ template <typename T>
15
+ BorrowingReference<T>::BorrowingReference(const OwningReference<T>& ref) {
15
16
  _value = ref._value;
16
17
  _isDeleted = ref._isDeleted;
17
18
  _strongRefCount = ref._strongRefCount;
@@ -20,7 +21,8 @@ template <typename T> BorrowingReference<T>::BorrowingReference(const OwningRefe
20
21
  (*_weakRefCount)++;
21
22
  }
22
23
 
23
- template <typename T> OwningReference<T> BorrowingReference<T>::lock() {
24
+ template <typename T>
25
+ OwningReference<T> BorrowingReference<T>::lock() {
24
26
  std::unique_lock lock(*_mutex);
25
27
 
26
28
  if (*_isDeleted) {
@@ -7,20 +7,22 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include <atomic>
10
11
  #include <cstddef>
11
12
  #include <mutex>
12
- #include <atomic>
13
13
 
14
14
  namespace margelo::nitro {
15
15
 
16
16
  // forward-declaration to avoid duplicate symbols
17
- template <typename T> class OwningReference;
17
+ template <typename T>
18
+ class OwningReference;
18
19
 
19
20
  /**
20
21
  A `BorrowingReference<T>` is a weak reference to a pointer created by `OwningReference<T>`.
21
22
  It can be locked to gain a strong `OwningReference<T>` again if it has not been deleted yet.
22
23
  */
23
- template <typename T> class BorrowingReference final {
24
+ template <typename T>
25
+ class BorrowingReference final {
24
26
  private:
25
27
  explicit BorrowingReference(const OwningReference<T>& ref);
26
28
 
@@ -35,7 +35,8 @@ constexpr uint64_t hashString(const char* str, size_t length) {
35
35
  *
36
36
  * String length is known at compile time.
37
37
  */
38
- template <size_t N> constexpr uint64_t hashString(const char (&str)[N]) {
38
+ template <size_t N>
39
+ constexpr uint64_t hashString(const char (&str)[N]) {
39
40
  return hashString(str, N - 1); // N includes the null terminator, so subtract 1
40
41
  }
41
42
 
@@ -17,13 +17,15 @@ private:
17
17
  Logger() = delete;
18
18
 
19
19
  public:
20
- template <typename... Args> static void log(const char* tag, const char* message, Args&&... args) {
20
+ template <typename... Args>
21
+ static void log(const char* tag, const char* message, Args&&... args) {
21
22
  std::string formattedMessage = format(message, std::forward<Args>(args)...);
22
23
  std::cout << "[Nitro." << tag << "] " << formattedMessage << std::endl;
23
24
  }
24
25
 
25
26
  private:
26
- template <typename... Args> static inline std::string format(const char* formatString, Args&&... args) {
27
+ template <typename... Args>
28
+ static inline std::string format(const char* formatString, Args&&... args) {
27
29
  #pragma clang diagnostic push
28
30
  #pragma clang diagnostic ignored "-Wformat-security"
29
31
  int size_s = std::snprintf(nullptr, 0, formatString, toCString(args)...) + 1; // Extra space for '\0'
@@ -47,7 +49,8 @@ private:
47
49
  return s;
48
50
  }
49
51
  // When the user passes any other type, just return that directly.
50
- template <typename T> static inline T toCString(T value) {
52
+ template <typename T>
53
+ static inline T toCString(T value) {
51
54
  return value;
52
55
  }
53
56
  };
@@ -8,7 +8,8 @@
8
8
  #pragma once
9
9
 
10
10
  namespace margelo::nitro {
11
- template <typename T> class OwningReference;
11
+ template <typename T>
12
+ class OwningReference;
12
13
  }
13
14
 
14
15
  #include "OwningReference.hpp"
@@ -29,7 +30,8 @@ namespace margelo::nitro {
29
30
  *
30
31
  * To create an `OwningLock<T>`, simply call `lock()` on an `OwningReference<T>`.
31
32
  */
32
- template <typename T> class OwningLock final {
33
+ template <typename T>
34
+ class OwningLock final {
33
35
  public:
34
36
  ~OwningLock() {
35
37
  _reference._mutex->unlock();
@@ -9,9 +9,9 @@
9
9
 
10
10
  #include "BorrowingReference.hpp"
11
11
  #include "OwningLock.hpp"
12
+ #include <atomic>
12
13
  #include <cstddef>
13
14
  #include <mutex>
14
- #include <atomic>
15
15
 
16
16
  namespace margelo::nitro {
17
17
 
@@ -24,7 +24,8 @@ namespace margelo::nitro {
24
24
  An `OwningReference<T>` can be weakified, which gives the user a `BorrowingReference<T>`.
25
25
  A `BorrowingReference<T>` can be locked to get an `OwningReference<T>` again, assuming it has not been deleted yet.
26
26
  */
27
- template <typename T> class OwningReference final {
27
+ template <typename T>
28
+ class OwningReference final {
28
29
  public:
29
30
  using Pointee = T;
30
31
 
@@ -32,8 +33,8 @@ public:
32
33
  OwningReference() : _value(nullptr), _isDeleted(nullptr), _strongRefCount(nullptr), _weakRefCount(nullptr), _mutex(nullptr) {}
33
34
 
34
35
  explicit OwningReference(T* value)
35
- : _value(value), _isDeleted(new bool(false)), _strongRefCount(new std::atomic_size_t(1)), _weakRefCount(new std::atomic_size_t(0)), _mutex(new std::mutex()) {
36
- }
36
+ : _value(value), _isDeleted(new bool(false)), _strongRefCount(new std::atomic_size_t(1)), _weakRefCount(new std::atomic_size_t(0)),
37
+ _mutex(new std::mutex()) {}
37
38
 
38
39
  OwningReference(const OwningReference& ref)
39
40
  : _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
@@ -41,7 +41,8 @@ public:
41
41
  /**
42
42
  * Get a friendly name of the type `T` (if possible, demangled)
43
43
  */
44
- template <typename T> static inline std::string getFriendlyTypename() {
44
+ template <typename T>
45
+ static inline std::string getFriendlyTypename() {
45
46
  std::string name = typeid(T).name();
46
47
  #if __has_include(<cxxabi.h>)
47
48
  int status = 0;
@@ -70,7 +71,8 @@ public:
70
71
  return name;
71
72
  }
72
73
 
73
- template <typename... Types> static inline std::string getFriendlyTypenames() {
74
+ template <typename... Types>
75
+ static inline std::string getFriendlyTypenames() {
74
76
  std::ostringstream stream;
75
77
  ((stream << TypeInfo::getFriendlyTypename<Types>() << ", "), ...);
76
78
  std::string string = stream.str();