5555#include < tuple>
5656#include < type_traits>
5757#include < typeinfo>
58- #include < unordered_map>
5958#include < unordered_set>
59+ #include < unordered_map>
6060#include < utility>
6161#include < variant>
6262#include < vector>
@@ -72,258 +72,3 @@ namespace REL
7272{
7373 using namespace std ::literals;
7474}
75-
76- namespace XSE
77- {
78- using namespace std ::literals;
79-
80- namespace stl
81- {
82- // owning pointer
83- template <
84- class T ,
85- class = std::enable_if_t <
86- std::is_pointer_v<T>>>
87- using owner = T;
88-
89- // non-owning pointer
90- template <
91- class T ,
92- class = std::enable_if_t <
93- std::is_pointer_v<T>>>
94- using observer = T;
95-
96- // non-null pointer
97- template <
98- class T ,
99- class = std::enable_if_t <
100- std::is_pointer_v<T>>>
101- using not_null = T;
102-
103- template <class T >
104- struct remove_cvptr
105- {
106- using type = std::remove_cv_t <std::remove_pointer_t <T>>;
107- };
108-
109- template <class T >
110- using remove_cvptr_t = typename remove_cvptr<T>::type;
111-
112- template <class C , class K >
113- concept transparent_comparator =
114- requires (
115- const K& a_transparent,
116- const typename C::key_type& a_key,
117- typename C::key_compare& a_compare) {
118- typename C::key_compare::is_transparent;
119- // clang-format off
120- { a_compare (a_transparent, a_key) } -> std::convertible_to<bool >;
121- { a_compare (a_key, a_transparent) } -> std::convertible_to<bool >;
122- // clang-format on
123- };
124-
125- template <class EF > //
126- requires (std::invocable<std::remove_reference_t <EF>>) //
127- class scope_exit
128- {
129- public:
130- // 1)
131- template <class Fn >
132- explicit scope_exit (Fn&& a_fn) //
133- noexcept (std::is_nothrow_constructible_v<EF, Fn> ||
134- std::is_nothrow_constructible_v<EF, Fn&>) //
135- requires(!std::is_same_v<std::remove_cvref_t <Fn>, scope_exit> &&
136- std::is_constructible_v<EF, Fn>)
137- {
138- static_assert (std::invocable<Fn>);
139-
140- if constexpr (!std::is_lvalue_reference_v<Fn> &&
141- std::is_nothrow_constructible_v<EF, Fn>) {
142- _fn.emplace (std::forward<Fn>(a_fn));
143- } else {
144- _fn.emplace (a_fn);
145- }
146- }
147-
148- // 2)
149- scope_exit (scope_exit&& a_rhs) //
150- noexcept (std::is_nothrow_move_constructible_v<EF> ||
151- std::is_nothrow_copy_constructible_v<EF>) //
152- requires (std::is_nothrow_move_constructible_v<EF> ||
153- std::is_copy_constructible_v<EF>)
154- {
155- static_assert (!(std::is_nothrow_move_constructible_v<EF> && !std::is_move_constructible_v<EF>));
156- static_assert (!(!std::is_nothrow_move_constructible_v<EF> && !std::is_copy_constructible_v<EF>));
157-
158- if (a_rhs.active ()) {
159- if constexpr (std::is_nothrow_move_constructible_v<EF>) {
160- _fn.emplace (std::forward<EF>(*a_rhs._fn ));
161- } else {
162- _fn.emplace (a_rhs._fn );
163- }
164- a_rhs.release ();
165- }
166- }
167-
168- // 3)
169- scope_exit (const scope_exit&) = delete ;
170-
171- ~scope_exit () noexcept
172- {
173- if (_fn.has_value ()) {
174- (*_fn)();
175- }
176- }
177-
178- void release () noexcept { _fn.reset (); }
179-
180- private:
181- [[nodiscard]] bool active () const noexcept { return _fn.has_value (); }
182-
183- std::optional<std::remove_reference_t <EF>> _fn;
184- };
185-
186- template <class EF >
187- scope_exit (EF) -> scope_exit<EF>;
188-
189- template <class F >
190- class counted_function_iterator
191- {
192- public:
193- using difference_type = std::ptrdiff_t ;
194- using value_type = std::remove_const_t <std::remove_reference_t <decltype (std::declval<F>()())>>;
195- using pointer = value_type*;
196- using reference = value_type&;
197- using iterator_category = std::input_iterator_tag;
198-
199- counted_function_iterator () noexcept = default ;
200-
201- counted_function_iterator (F a_fn, std::size_t a_count) noexcept :
202- _fn (std::move(a_fn)),
203- _left (a_count)
204- {}
205-
206- [[nodiscard]] reference operator *() const //
207- noexcept (noexcept (std::declval<F>()()))
208- {
209- assert (_fn != std::nullopt );
210- return (*_fn)();
211- }
212-
213- [[nodiscard]] pointer operator ->() const
214- {
215- return std::pointer_traits<pointer>::pointer_to (operator *());
216- }
217-
218- [[nodiscard]] friend bool operator ==(
219- const counted_function_iterator& a_lhs,
220- const counted_function_iterator& a_rhs) noexcept
221- {
222- return a_lhs._left == a_rhs._left ;
223- }
224-
225- counted_function_iterator& operator ++() noexcept
226- {
227- assert (_left > 0 );
228- _left -= 1 ;
229- return *this ;
230- }
231-
232- counted_function_iterator operator ++(int ) noexcept
233- {
234- counted_function_iterator tmp{ *this };
235- operator ++();
236- return tmp;
237- }
238-
239- private:
240- std::optional<F> _fn;
241- std::size_t _left{ 0 };
242- };
243- }
244- }
245-
246- namespace XSE
247- {
248- namespace stl
249- {
250- template <class T >
251- class atomic_ref :
252- public std::atomic_ref<T>
253- {
254- private:
255- using super = std::atomic_ref<T>;
256-
257- public:
258- using value_type = typename super::value_type;
259-
260- explicit atomic_ref (volatile T& a_obj) noexcept (std::is_nothrow_constructible_v<super, value_type&>) :
261- super(const_cast <value_type&>(a_obj))
262- {}
263-
264- using super::super;
265- using super::operator =;
266- };
267-
268- template <class T >
269- atomic_ref (volatile T&) -> atomic_ref<T>;
270-
271- template class atomic_ref <std::int8_t >;
272- template class atomic_ref <std::uint8_t >;
273- template class atomic_ref <std::int16_t >;
274- template class atomic_ref <std::uint16_t >;
275- template class atomic_ref <std::int32_t >;
276- template class atomic_ref <std::uint32_t >;
277- template class atomic_ref <std::int64_t >;
278- template class atomic_ref <std::uint64_t >;
279-
280- static_assert (atomic_ref<std::int8_t >::is_always_lock_free);
281- static_assert (atomic_ref<std::uint8_t >::is_always_lock_free);
282- static_assert (atomic_ref<std::int16_t >::is_always_lock_free);
283- static_assert (atomic_ref<std::uint16_t >::is_always_lock_free);
284- static_assert (atomic_ref<std::int32_t >::is_always_lock_free);
285- static_assert (atomic_ref<std::uint32_t >::is_always_lock_free);
286- static_assert (atomic_ref<std::int64_t >::is_always_lock_free);
287- static_assert (atomic_ref<std::uint64_t >::is_always_lock_free);
288-
289- template <class T >
290- struct ssizeof
291- {
292- [[nodiscard]] constexpr operator std::ptrdiff_t () const noexcept { return value; }
293-
294- [[nodiscard]] constexpr std::ptrdiff_t operator ()() const noexcept { return value; }
295-
296- static constexpr auto value = static_cast <std::ptrdiff_t >(sizeof (T));
297- };
298-
299- template <class T >
300- inline constexpr auto ssizeof_v = ssizeof<T>::value;
301-
302- template <class T >
303- void memzero (volatile T* a_ptr, std::size_t a_size = sizeof (T))
304- {
305- const auto begin = reinterpret_cast <volatile char *>(a_ptr);
306- constexpr char val{ 0 };
307- std::fill_n (begin, a_size, val);
308- }
309-
310- template <class ... Args>
311- [[nodiscard]] inline auto pun_bits (Args... a_args) //
312- requires(std::same_as<std::remove_cv_t <Args>, bool > && ...)
313- {
314- constexpr auto ARGC = sizeof ...(Args);
315-
316- std::bitset<ARGC> bits;
317- std::size_t i = 0 ;
318- ((bits[i++] = a_args), ...);
319-
320- if constexpr (ARGC <= std::numeric_limits<unsigned long >::digits) {
321- return bits.to_ulong ();
322- } else if constexpr (ARGC <= std::numeric_limits<unsigned long long >::digits) {
323- return bits.to_ullong ();
324- } else {
325- static_assert (false && sizeof ...(Args));
326- }
327- }
328- }
329- }
0 commit comments