Skip to content

Commit a74666e

Browse files
Merge pull request #18 from mcpplibs/refactor-complete-conversion
Refactor numeric type handling and enhance conversion modules
2 parents 109fdef + 7b39fe4 commit a74666e

13 files changed

Lines changed: 573 additions & 170 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ CMakeCache.txt
4848
CMakeFiles/
4949
cmake_install.cmake
5050
Makefile
51+
cmake-build-*/
5152

5253
# IDE
5354
/.idea

src/conversion/conversion.cppm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ export module mcpplibs.primitives.conversion;
44

55
export import mcpplibs.primitives.conversion.traits;
66
export import mcpplibs.primitives.conversion.underlying;
7+
export import mcpplibs.primitives.conversion.mixing;
8+
export import mcpplibs.primitives.conversion.primitive;

src/conversion/mixing.cppm

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
module;
2+
3+
#include <expected>
4+
#include <type_traits>
5+
6+
export module mcpplibs.primitives.conversion.mixing;
7+
8+
import mcpplibs.primitives.conversion.traits;
9+
import mcpplibs.primitives.conversion.underlying;
10+
import mcpplibs.primitives.primitive;
11+
import mcpplibs.primitives.underlying;
12+
13+
namespace mcpplibs::primitives::conversion::details {
14+
15+
template <meta::primitive_type Primitive>
16+
using primitive_value_t =
17+
meta::traits<std::remove_cvref_t<Primitive>>::value_type;
18+
19+
template <meta::primitive_type Dest, underlying_type Src, typename Caster>
20+
constexpr auto cast_to_primitive_value(Src value, Caster caster) noexcept
21+
-> std::remove_cvref_t<Dest> {
22+
using dest_type = std::remove_cvref_t<Dest>;
23+
using dest_value_type = primitive_value_t<dest_type>;
24+
25+
return dest_type{caster.template operator()<dest_value_type>(value)};
26+
}
27+
28+
template <meta::primitive_type Dest, underlying_type Src, typename Caster>
29+
constexpr auto cast_to_primitive_result(Src value, Caster caster)
30+
-> cast_result<std::remove_cvref_t<Dest>> {
31+
using dest_type = std::remove_cvref_t<Dest>;
32+
using dest_value_type = primitive_value_t<dest_type>;
33+
34+
auto const converted = caster.template operator()<dest_value_type>(value);
35+
if (!converted.has_value()) {
36+
return std::unexpected(converted.error());
37+
}
38+
39+
return dest_type{*converted};
40+
}
41+
42+
} // namespace mcpplibs::primitives::conversion::details
43+
44+
export namespace mcpplibs::primitives::conversion {
45+
46+
template <meta::primitive_type Dest, underlying_type Src>
47+
constexpr auto unchecked_cast(Src value) noexcept -> std::remove_cvref_t<Dest> {
48+
return details::cast_to_primitive_value<Dest>(
49+
value, []<underlying_type DestValue, underlying_type SrcValue>(
50+
SrcValue source) {
51+
return conversion::unchecked_cast<DestValue>(source);
52+
});
53+
}
54+
55+
template <underlying_type Dest, meta::primitive_type Src>
56+
constexpr auto unchecked_cast(Src const &value) noexcept -> std::remove_cv_t<Dest> {
57+
return conversion::unchecked_cast<std::remove_cv_t<Dest>>(value.load());
58+
}
59+
60+
template <meta::primitive_type Dest, underlying_type Src>
61+
constexpr auto checked_cast(Src value)
62+
-> cast_result<std::remove_cvref_t<Dest>> {
63+
return details::cast_to_primitive_result<Dest>(
64+
value, []<underlying_type DestValue, underlying_type SrcValue>(
65+
SrcValue source) {
66+
return conversion::checked_cast<DestValue>(source);
67+
});
68+
}
69+
70+
template <underlying_type Dest, meta::primitive_type Src>
71+
constexpr auto checked_cast(Src const &value)
72+
-> cast_result<std::remove_cv_t<Dest>> {
73+
return conversion::checked_cast<std::remove_cv_t<Dest>>(value.load());
74+
}
75+
76+
template <meta::primitive_type Dest, underlying_type Src>
77+
constexpr auto saturating_cast(Src value) noexcept
78+
-> std::remove_cvref_t<Dest> {
79+
return details::cast_to_primitive_value<Dest>(
80+
value, []<underlying_type DestValue, underlying_type SrcValue>(
81+
SrcValue source) {
82+
return conversion::saturating_cast<DestValue>(source);
83+
});
84+
}
85+
86+
template <underlying_type Dest, meta::primitive_type Src>
87+
constexpr auto saturating_cast(Src const &value) noexcept
88+
-> std::remove_cv_t<Dest> {
89+
return conversion::saturating_cast<std::remove_cv_t<Dest>>(value.load());
90+
}
91+
92+
template <meta::primitive_type Dest, underlying_type Src>
93+
constexpr auto truncating_cast(Src value) noexcept
94+
-> std::remove_cvref_t<Dest> {
95+
return details::cast_to_primitive_value<Dest>(
96+
value, []<underlying_type DestValue, underlying_type SrcValue>(
97+
SrcValue source) {
98+
return conversion::truncating_cast<DestValue>(source);
99+
});
100+
}
101+
102+
template <underlying_type Dest, meta::primitive_type Src>
103+
constexpr auto truncating_cast(Src const &value) noexcept
104+
-> std::remove_cv_t<Dest> {
105+
return conversion::truncating_cast<std::remove_cv_t<Dest>>(value.load());
106+
}
107+
108+
template <meta::primitive_type Dest, underlying_type Src>
109+
constexpr auto exact_cast(Src value)
110+
-> cast_result<std::remove_cvref_t<Dest>> {
111+
return details::cast_to_primitive_result<Dest>(
112+
value, []<underlying_type DestValue, underlying_type SrcValue>(
113+
SrcValue source) {
114+
return conversion::exact_cast<DestValue>(source);
115+
});
116+
}
117+
118+
template <underlying_type Dest, meta::primitive_type Src>
119+
constexpr auto exact_cast(Src const &value)
120+
-> cast_result<std::remove_cv_t<Dest>> {
121+
return conversion::exact_cast<std::remove_cv_t<Dest>>(value.load());
122+
}
123+
124+
} // namespace mcpplibs::primitives::conversion

src/conversion/primitive.cppm

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module;
2+
3+
#include <type_traits>
4+
5+
export module mcpplibs.primitives.conversion.primitive;
6+
7+
import mcpplibs.primitives.conversion.traits;
8+
import mcpplibs.primitives.conversion.mixing;
9+
import mcpplibs.primitives.primitive;
10+
11+
export namespace mcpplibs::primitives::conversion {
12+
13+
template <meta::primitive_type Dest, meta::primitive_type Src>
14+
constexpr auto unchecked_cast(Src const &value) noexcept
15+
-> std::remove_cvref_t<Dest> {
16+
return conversion::unchecked_cast<std::remove_cvref_t<Dest>>(value.load());
17+
}
18+
19+
template <meta::primitive_type Dest, meta::primitive_type Src>
20+
constexpr auto checked_cast(Src const &value)
21+
-> cast_result<std::remove_cvref_t<Dest>> {
22+
return conversion::checked_cast<std::remove_cvref_t<Dest>>(value.load());
23+
}
24+
25+
template <meta::primitive_type Dest, meta::primitive_type Src>
26+
constexpr auto saturating_cast(Src const &value) noexcept
27+
-> std::remove_cvref_t<Dest> {
28+
return conversion::saturating_cast<std::remove_cvref_t<Dest>>(value.load());
29+
}
30+
31+
template <meta::primitive_type Dest, meta::primitive_type Src>
32+
constexpr auto truncating_cast(Src const &value) noexcept
33+
-> std::remove_cvref_t<Dest> {
34+
return conversion::truncating_cast<std::remove_cvref_t<Dest>>(value.load());
35+
}
36+
37+
template <meta::primitive_type Dest, meta::primitive_type Src>
38+
constexpr auto exact_cast(Src const &value)
39+
-> cast_result<std::remove_cvref_t<Dest>> {
40+
return conversion::exact_cast<std::remove_cvref_t<Dest>>(value.load());
41+
}
42+
43+
} // namespace mcpplibs::primitives::conversion

0 commit comments

Comments
 (0)