@auto_js/utility 0.0.1

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 (41) hide show
  1. package/CMakeLists.txt +45 -0
  2. package/LICENSE +13 -0
  3. package/_module.cc +14 -0
  4. package/assertions.cc +32 -0
  5. package/container/mutable_priority_queue.cc +35 -0
  6. package/container/sealed_map.cc +121 -0
  7. package/container/segmented_priority_queue.cc +105 -0
  8. package/container/tinker_queue.cc +73 -0
  9. package/functional/bind.cc +151 -0
  10. package/functional/elide.cc +52 -0
  11. package/functional/flat_tuple.cc +90 -0
  12. package/functional/function_constant.cc +58 -0
  13. package/functional/function_ref.cc +68 -0
  14. package/functional/functional.cc +107 -0
  15. package/functional/regular_return.cc +55 -0
  16. package/include/auto_js/chunk_view.h +363 -0
  17. package/include/auto_js/no_unique_address.h +8 -0
  18. package/memory/autorelease_pool.cc +281 -0
  19. package/memory/comparator.cc +53 -0
  20. package/memory/memory.cc +64 -0
  21. package/memory/noinit_allocator.cc +64 -0
  22. package/meta/algorithm.cc +74 -0
  23. package/package.json +11 -0
  24. package/platform/lockable.cc +261 -0
  25. package/platform/shim/darwin.cc +8 -0
  26. package/platform/stop_token.cc +107 -0
  27. package/platform/timer.cc +175 -0
  28. package/platform/timer.h.cc +36 -0
  29. package/type_traits/function_traits.cc +173 -0
  30. package/type_traits/transform.cc +60 -0
  31. package/type_traits/type_of.cc +72 -0
  32. package/type_traits/type_pack.cc +116 -0
  33. package/type_traits/type_traits.cc +5 -0
  34. package/utility/constant_wrapper.cc +57 -0
  35. package/utility/covariant_value.cc +33 -0
  36. package/utility/facade.cc +126 -0
  37. package/utility/hash.cc +37 -0
  38. package/utility/ranges.cc +55 -0
  39. package/utility/string.cc +328 -0
  40. package/utility/utility.cc +150 -0
  41. package/utility/variant.cc +26 -0
@@ -0,0 +1,90 @@
1
+ module;
2
+ #include "auto_js/no_unique_address.h"
3
+ #include <type_traits>
4
+ #include <utility>
5
+ export module util:functional.flat_tuple;
6
+
7
+ namespace util {
8
+
9
+ // Internal `flat_tuple` element storage
10
+ template <std::size_t Index, class Type>
11
+ class flat_tuple_element {
12
+ public:
13
+ flat_tuple_element() = default;
14
+ constexpr explicit flat_tuple_element(Type&& value) : value_{std::move(value)} {}
15
+ constexpr explicit flat_tuple_element(const Type& value) : value_{value} {}
16
+
17
+ using index_type = std::integral_constant<std::size_t, Index>;
18
+ constexpr auto get(index_type /*index*/) & -> Type& { return value_; }
19
+ constexpr auto get(index_type /*index*/) && -> Type&& { return std::move(value_); }
20
+ [[nodiscard]] constexpr auto get(index_type /*index*/) const& -> const Type& { return value_; }
21
+
22
+ private:
23
+ NO_UNIQUE_ADDRESS Type value_;
24
+ };
25
+
26
+ // Specialization for reference types
27
+ template <std::size_t Index, class Type>
28
+ class flat_tuple_element<Index, Type&> {
29
+ public:
30
+ flat_tuple_element() = delete;
31
+ constexpr explicit flat_tuple_element(Type& value) : value_{&value} {}
32
+
33
+ using index_type = std::integral_constant<std::size_t, Index>;
34
+ constexpr auto get(index_type /*index*/) & -> Type& { return *value_; }
35
+ constexpr auto get(index_type /*index*/) && -> Type& { return *value_; }
36
+ [[nodiscard]] constexpr auto get(index_type /*index*/) const& -> const Type& { return *value_; }
37
+
38
+ private:
39
+ NO_UNIQUE_ADDRESS Type* value_;
40
+ };
41
+
42
+ // Internal `flat_tuple` helper providing access into private `flat_tuple_element` via friend
43
+ // visibility
44
+ constexpr auto flat_tuple_get(auto index, auto&& tuple) -> auto&& {
45
+ return std::forward<decltype(tuple)>(tuple).get(index);
46
+ }
47
+
48
+ // Internal `flat_tuple_storage` element collection storage
49
+ template <class Indices, class... Types>
50
+ class flat_tuple_storage;
51
+
52
+ template <class... Types>
53
+ using flat_tuple_storage_t = flat_tuple_storage<std::make_index_sequence<sizeof...(Types)>, Types...>;
54
+
55
+ template <std::size_t... Index, class... Type>
56
+ class flat_tuple_storage<std::index_sequence<Index...>, Type...> : private flat_tuple_element<Index, Type>... {
57
+ public:
58
+ flat_tuple_storage() = default;
59
+ constexpr explicit flat_tuple_storage(auto&&... values) :
60
+ flat_tuple_element<Index, Type>{std::forward<decltype(values)>(values)}... {}
61
+
62
+ private:
63
+ constexpr friend auto flat_tuple_get(auto, auto&&) -> auto&&;
64
+ using flat_tuple_element<Index, Type>::get...;
65
+ };
66
+
67
+ // Simple replacement for `std::tuple` which is trivially copyable in the case its members are.
68
+ // See: `static_assert(!std::is_trivially_copyable_v<std::tuple<int>>);`
69
+ export template <class... Types>
70
+ struct flat_tuple : flat_tuple_storage_t<Types...> {
71
+ using flat_tuple_storage_t<Types...>::flat_tuple_storage_t;
72
+ };
73
+
74
+ // `std::get` replacement for `flat_tuple`
75
+ export template <std::size_t Index, class... Types>
76
+ constexpr auto get(flat_tuple<Types...>& tuple) -> auto& {
77
+ return flat_tuple_get(std::integral_constant<std::size_t, Index>{}, tuple);
78
+ }
79
+
80
+ export template <std::size_t Index, class... Types>
81
+ constexpr auto get(flat_tuple<Types...>&& tuple) -> auto&& {
82
+ return flat_tuple_get(std::integral_constant<std::size_t, Index>{}, std::move(tuple));
83
+ }
84
+
85
+ export template <std::size_t Index, class... Types>
86
+ constexpr auto get(const flat_tuple<Types...>& tuple) -> const auto& {
87
+ return flat_tuple_get(std::integral_constant<std::size_t, Index>{}, tuple);
88
+ }
89
+
90
+ } // namespace util
@@ -0,0 +1,58 @@
1
+ module;
2
+ #include <concepts>
3
+ #include <utility>
4
+ export module util:functional.function_constant;
5
+ import :type_traits;
6
+
7
+ namespace util {
8
+
9
+ // Kind of related to P3774 [https://isocpp.org/files/papers/P3774R0.html] but returns an invocable
10
+ // which can be inferred with `function_signature_t`.
11
+ export template <auto Invocable>
12
+ struct function_constant;
13
+
14
+ export template <auto Invocable>
15
+ constexpr auto fn = function_constant<Invocable>{};
16
+
17
+ template <auto Invocable, class Function, class Signature>
18
+ struct function_constant_of;
19
+
20
+ template <auto Invocable, class Function>
21
+ struct function_constant_with;
22
+
23
+ // Specialization for inferrable signatures
24
+ template <auto Invocable>
25
+ requires requires { typename function_signature_t<decltype(Invocable)>; }
26
+ struct function_constant<Invocable> : function_constant_of<Invocable, decltype(Invocable), function_signature_t<decltype(Invocable)>> {};
27
+
28
+ // Overloaded invocable
29
+ template <auto Invocable>
30
+ struct function_constant : function_constant_with<Invocable, decltype(Invocable)> {};
31
+
32
+ // Free function or invocable object
33
+ template <auto Invocable, class Function, class... Args, bool Nx, class Result>
34
+ struct function_constant_of<Invocable, Function, auto(Args...) noexcept(Nx)->Result> {
35
+ constexpr auto operator()(Args... args) const noexcept(Nx) -> Result {
36
+ return Invocable(std::forward<Args>(args)...);
37
+ }
38
+ };
39
+
40
+ // Member function pointer
41
+ template <auto Invocable, class Type, class Function, class That, class... Args, bool Nx, class Result>
42
+ struct function_constant_of<Invocable, Function Type::*, auto(That, Args...) noexcept(Nx)->Result> {
43
+ constexpr auto operator()(That that, Args... args) const noexcept(Nx) -> Result {
44
+ return (std::forward<That>(that).*Invocable)(std::forward<Args>(args)...);
45
+ }
46
+ };
47
+
48
+ // Overloaded function
49
+ template <auto Invocable, class Function>
50
+ struct function_constant_with {
51
+ template <class... Args>
52
+ constexpr auto operator()(Args&&... args) const noexcept(std::is_nothrow_invocable_v<Function, Args...>) -> decltype(auto)
53
+ requires std::invocable<Function, Args...> {
54
+ return Invocable(std::forward<Args>(args)...);
55
+ }
56
+ };
57
+
58
+ } // namespace util
@@ -0,0 +1,68 @@
1
+ module;
2
+ #include <concepts>
3
+ #include <type_traits>
4
+ #include <utility>
5
+ export module util:functional.function_ref;
6
+ import :functional.elide;
7
+ import :type_traits;
8
+
9
+ namespace util {
10
+
11
+ export template <class Signature>
12
+ class function_ref;
13
+
14
+ template <class Result, bool Nx, class... Args>
15
+ class function_ref<auto(Args...) noexcept(Nx)->Result> {
16
+ private:
17
+ template <class Type>
18
+ constexpr explicit function_ref(std::type_identity<Type> /*tag*/, void* ptr) :
19
+ invoke_{[](void* ptr, Args... args) noexcept(Nx) -> Result {
20
+ auto& object = *static_cast<Type*>(ptr);
21
+ return object(std::forward<Args>(args)...);
22
+ }},
23
+ ptr_{ptr} {}
24
+
25
+ public:
26
+ using signature_type = auto(Args...) noexcept(Nx) -> Result;
27
+
28
+ // NOLINTNEXTLINE(google-explicit-constructor)
29
+ constexpr function_ref(signature_type* function) :
30
+ function_ref{std::type_identity<signature_type>{}, static_cast<void*>(function)} {}
31
+
32
+ template <std::invocable<Args...> Object>
33
+ requires(type<Object> != type<function_ref>)
34
+ // NOLINTNEXTLINE(google-explicit-constructor)
35
+ constexpr function_ref(Object& object) :
36
+ function_ref{std::type_identity<Object>{}, static_cast<void*>(&object)} {}
37
+
38
+ // Explicit to avoid automatic binding to temporary objects
39
+ template <std::invocable<Args...> Object>
40
+ requires(type<Object> != type<function_ref>)
41
+ constexpr explicit function_ref(const Object& object) :
42
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
43
+ function_ref{std::type_identity<const Object>{}, const_cast<void*>(static_cast<const void*>(&object))} {}
44
+
45
+ // Bound function constant
46
+ template <class Object, std::invocable<Object&, Args...> Function>
47
+ requires std::is_empty_v<Function>
48
+ constexpr explicit function_ref(Function /*function*/, Object& bound) :
49
+ invoke_{[](void* ptr, Args... args) noexcept(Nx) -> Result {
50
+ auto& object = *static_cast<Object*>(ptr);
51
+ constexpr auto function = Function{};
52
+ return function(object, std::forward<Args>(args)...);
53
+ }},
54
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
55
+ ptr_{const_cast<void*>(static_cast<const void*>(&bound))} {}
56
+
57
+ constexpr auto operator()(Args... args) const noexcept(Nx) -> Result {
58
+ return invoke_(ptr_, std::forward<Args>(args)...);
59
+ }
60
+
61
+ private:
62
+ using invoke_type = auto(void*, Args...) noexcept(Nx) -> Result;
63
+
64
+ invoke_type* invoke_;
65
+ void* ptr_;
66
+ };
67
+
68
+ } // namespace util
@@ -0,0 +1,107 @@
1
+ module;
2
+ #include <functional>
3
+ #include <utility>
4
+ export module util:functional;
5
+ export import :functional.bind;
6
+ export import :functional.elide;
7
+ export import :functional.function_constant;
8
+ export import :functional.function_ref;
9
+ export import :functional.regular_return;
10
+ import :type_traits;
11
+
12
+ namespace util {
13
+
14
+ // https://en.cppreference.com/w/cpp/utility/variant/visit
15
+ export template <class... Visitors>
16
+ struct overloaded : Visitors... {
17
+ using Visitors::operator()...;
18
+ };
19
+
20
+ // Holder for functions in libc++ which doesn't support std::move_only_function
21
+ #if defined(__cpp_lib_move_only_function) && !defined(DEBUG)
22
+
23
+ export template <class Signature>
24
+ using maybe_move_only_function = std::move_only_function<Signature>;
25
+
26
+ export template <class Fn>
27
+ auto make_indirect_moveable_function(Fn fn) {
28
+ return fn;
29
+ }
30
+
31
+ #else
32
+
33
+ export template <class Signature>
34
+ using maybe_move_only_function = std::function<remove_function_cvref_t<Signature>>;
35
+
36
+ export template <class Fn>
37
+ auto make_indirect_moveable_function(Fn&& fn) {
38
+ auto fn_ptr = std::make_shared<std::remove_cvref_t<Fn>>(std::forward<Fn>(fn));
39
+ return [ = ](auto&&... args) -> decltype(auto) {
40
+ return (*fn_ptr)(std::forward<decltype(args)>(args)...);
41
+ };
42
+ }
43
+
44
+ #endif
45
+
46
+ // Hide `-Wunused-value` warnings
47
+ export constexpr auto unused = [](auto&& /*nothing*/) -> void {};
48
+
49
+ // Invoke the given callable as a base class of itself. cvref qualifiers are forwarded, so `Type` is
50
+ // expected to be unqualified.
51
+ export template <class Type, class From>
52
+ constexpr auto invoke_as(From&& func, auto&&... args)
53
+ -> decltype(std::declval<apply_cvref_t<From, Type>>()(std::declval<decltype(args)>()...)) {
54
+ return static_cast<apply_cvref_t<From, Type>>(std::forward<decltype(func)>(func))(std::forward<decltype(args)>(args)...);
55
+ }
56
+
57
+ // Invoke the given callable using an explicit and possibly shadowed `operator()()` on a base class,
58
+ // but without erasing the pointer type for deduced `this`. The syntax here is messy, and
59
+ // `InvokeAsType_` can be shadowed by the base class. Also, clang has some really spooky behavior
60
+ // which is resolved by breaking out invocations to deduced-this instances.
61
+ export template <class InvokeAsType_>
62
+ constexpr auto invoke_this_as(auto&& func, auto&&... args)
63
+ // This is functionally the same as ` -> decltype(auto)` but works around the error:
64
+ // 'invoke_as<...>' with deduced return type cannot be used before it is defined
65
+ -> decltype(std::declval<decltype(func)>().InvokeAsType_::operator()(std::declval<decltype(args)>()...)) {
66
+ return std::forward<decltype(func)>(func).InvokeAsType_::operator()(std::forward<decltype(args)>(args)...);
67
+ }
68
+
69
+ // Invoke the given function with the constant expression matching a runtime value.
70
+ export constexpr auto template_switch(const auto& value, auto case_pack, auto invoke) -> decltype(auto) {
71
+ auto dispatch = [ & ](this const auto& self, auto case_, auto... cases) -> decltype(auto) {
72
+ if (value == case_) {
73
+ return invoke(case_);
74
+ } else {
75
+ if constexpr (sizeof...(cases) == 0) {
76
+ // default
77
+ return invoke();
78
+ } else {
79
+ return self(cases...);
80
+ }
81
+ }
82
+ };
83
+ const auto [... cases ] = case_pack;
84
+ // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
85
+ return dispatch(cases...);
86
+ }
87
+
88
+ // libc++'s `std::reference_wrapper` causes a template instantiation while looking for
89
+ // `result_type`. That breaks our transfer machinery.
90
+ export template <class Type>
91
+ class reference_wrapper {
92
+ public:
93
+ // NOLINTNEXTLINE(google-explicit-constructor)
94
+ constexpr reference_wrapper(Type& value) : value_{&value} {}
95
+
96
+ constexpr auto operator()(auto&&... args) const
97
+ -> decltype(std::declval<Type&>()(std::declval<decltype(args)>()...)) {
98
+ return (*value_)(std::forward<decltype(args)>(args)...);
99
+ }
100
+
101
+ constexpr auto get() const -> Type& { return *value_; }
102
+
103
+ private:
104
+ Type* value_;
105
+ };
106
+
107
+ } // namespace util
@@ -0,0 +1,55 @@
1
+ module;
2
+ #include <utility>
3
+ export module util:functional.regular_return;
4
+ import :type_traits;
5
+ import :utility;
6
+
7
+ namespace util {
8
+
9
+ // Value wrapper which can accept void values. `operator*` will return the underlying value.
10
+ template <class Type>
11
+ class regular_value {
12
+ public:
13
+ constexpr explicit regular_value(Type value) :
14
+ value_{std::move(value)} {}
15
+
16
+ constexpr auto operator*() && -> Type { return std::move(value_); }
17
+ constexpr auto value_or(const auto& /*nothing*/) && -> Type { return *std::move(*this); };
18
+
19
+ private:
20
+ Type value_;
21
+ };
22
+
23
+ template <>
24
+ class regular_value<void> {
25
+ public:
26
+ constexpr auto operator*() const -> void {}
27
+
28
+ template <class Type>
29
+ constexpr auto value_or(Type value) -> Type { return value; };
30
+ };
31
+
32
+ // Wraps the given invocable. When invoked it returns `regular_value<T>` of the function return
33
+ // value.
34
+ export template <class Type>
35
+ class regular_return {
36
+ public:
37
+ constexpr explicit regular_return(Type invoke) :
38
+ invoke_{std::move(invoke)} {}
39
+
40
+ constexpr auto operator()(this auto&& self, auto&&... args)
41
+ -> regular_value<std::invoke_result_t<util::apply_cvref_t<decltype(self), Type>, decltype(args)...>> {
42
+ using result_type = std::invoke_result_t<util::apply_cvref_t<decltype(self), Type>, decltype(args)...>;
43
+ if constexpr (std::is_void_v<result_type>) {
44
+ std::forward<decltype(self)>(self).invoke_(std::forward<decltype(args)>(args)...);
45
+ return regular_value<void>{};
46
+ } else {
47
+ return regular_value<result_type>{std::forward<decltype(self)>(self).invoke_(std::forward<decltype(args)>(args)...)};
48
+ }
49
+ }
50
+
51
+ private:
52
+ Type invoke_;
53
+ };
54
+
55
+ } // namespace util