Skip to content

Commit b3c8bff

Browse files
committed
feat: move things
1 parent 4830431 commit b3c8bff

4 files changed

Lines changed: 115 additions & 256 deletions

File tree

include/REX/BASE.h

Lines changed: 1 addition & 256 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
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-
}

include/REX/REX.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "REX/REX/AtomicRef.h"
34
#include "REX/REX/CAST.h"
45
#include "REX/REX/CONVERT.h"
56
#include "REX/REX/Enum.h"
@@ -8,6 +9,7 @@
89
#include "REX/REX/JSON.h"
910
#include "REX/REX/LOG.h"
1011
#include "REX/REX/MemoryMap.h"
12+
#include "REX/REX/ScopeExit.h"
1113
#include "REX/REX/Setting.h"
1214
#include "REX/REX/Singleton.h"
1315
#include "REX/REX/StaticString.h"

include/REX/REX/AtomicRef.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include "REX/BASE.h"
4+
5+
namespace REX
6+
{
7+
template <class T>
8+
class TAtomicRef :
9+
public std::atomic_ref<T>
10+
{
11+
private:
12+
using super = std::atomic_ref<T>;
13+
14+
public:
15+
using value_type = typename super::value_type;
16+
17+
explicit TAtomicRef(volatile T& a_obj) noexcept(std::is_nothrow_constructible_v<super, value_type&>) :
18+
super(const_cast<value_type&>(a_obj))
19+
{}
20+
21+
using super::super;
22+
using super::operator=;
23+
};
24+
25+
template <class T>
26+
TAtomicRef(volatile T&) -> TAtomicRef<T>;
27+
28+
template class TAtomicRef<std::int8_t>;
29+
template class TAtomicRef<std::uint8_t>;
30+
template class TAtomicRef<std::int16_t>;
31+
template class TAtomicRef<std::uint16_t>;
32+
template class TAtomicRef<std::int32_t>;
33+
template class TAtomicRef<std::uint32_t>;
34+
template class TAtomicRef<std::int64_t>;
35+
template class TAtomicRef<std::uint64_t>;
36+
37+
static_assert(TAtomicRef<std::int8_t>::is_always_lock_free);
38+
static_assert(TAtomicRef<std::uint8_t>::is_always_lock_free);
39+
static_assert(TAtomicRef<std::int16_t>::is_always_lock_free);
40+
static_assert(TAtomicRef<std::uint16_t>::is_always_lock_free);
41+
static_assert(TAtomicRef<std::int32_t>::is_always_lock_free);
42+
static_assert(TAtomicRef<std::uint32_t>::is_always_lock_free);
43+
static_assert(TAtomicRef<std::int64_t>::is_always_lock_free);
44+
static_assert(TAtomicRef<std::uint64_t>::is_always_lock_free);
45+
}

include/REX/REX/ScopeExit.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#pragma once
2+
3+
#include "REX/BASE.h"
4+
5+
namespace REX
6+
{
7+
template <class EF>
8+
requires(std::invocable<std::remove_reference_t<EF>>)
9+
class TScopeExit
10+
{
11+
public:
12+
template <class Fn>
13+
explicit TScopeExit(Fn&& a_fn)
14+
noexcept(std::is_nothrow_constructible_v<EF, Fn> ||
15+
std::is_nothrow_constructible_v<EF, Fn&>)
16+
requires(!std::is_same_v<std::remove_cvref_t<Fn>, TScopeExit> &&
17+
std::is_constructible_v<EF, Fn>)
18+
{
19+
static_assert(std::invocable<Fn>);
20+
21+
if constexpr (!std::is_lvalue_reference_v<Fn> &&
22+
std::is_nothrow_constructible_v<EF, Fn>) {
23+
_fn.emplace(std::forward<Fn>(a_fn));
24+
} else {
25+
_fn.emplace(a_fn);
26+
}
27+
}
28+
29+
TScopeExit(TScopeExit&& a_rhs)
30+
noexcept(std::is_nothrow_move_constructible_v<EF> ||
31+
std::is_nothrow_copy_constructible_v<EF>)
32+
requires(std::is_nothrow_move_constructible_v<EF> ||
33+
std::is_copy_constructible_v<EF>)
34+
{
35+
static_assert(!(std::is_nothrow_move_constructible_v<EF> && !std::is_move_constructible_v<EF>));
36+
static_assert(!(!std::is_nothrow_move_constructible_v<EF> && !std::is_copy_constructible_v<EF>));
37+
38+
if (a_rhs.active()) {
39+
if constexpr (std::is_nothrow_move_constructible_v<EF>) {
40+
_fn.emplace(std::forward<EF>(*a_rhs._fn));
41+
} else {
42+
_fn.emplace(a_rhs._fn);
43+
}
44+
a_rhs.release();
45+
}
46+
}
47+
48+
TScopeExit(const TScopeExit&) = delete;
49+
50+
~TScopeExit() noexcept
51+
{
52+
if (_fn.has_value()) {
53+
(*_fn)();
54+
}
55+
}
56+
57+
void release() noexcept { _fn.reset(); }
58+
59+
private:
60+
[[nodiscard]] bool active() const noexcept { return _fn.has_value(); }
61+
62+
std::optional<std::remove_reference_t<EF>> _fn;
63+
};
64+
65+
template <class EF>
66+
TScopeExit(EF) -> TScopeExit<EF>;
67+
}

0 commit comments

Comments
 (0)