File tree 8 files changed +82
-2
lines changed 8 files changed +82
-2
lines changed Original file line number Diff line number Diff line change 8
8
#include < safe/int.hpp>
9
9
#include < safe/match.hpp>
10
10
#include < safe/object.hpp>
11
+ #include < safe/safe_cast.hpp>
11
12
#include < safe/value.hpp>
12
13
#include < safe/var.hpp>
Original file line number Diff line number Diff line change @@ -37,12 +37,12 @@ template <typename T> struct unsafe_cast_ferry {
37
37
38
38
template <typename T>
39
39
requires (safe::Var<T>)
40
- [[nodiscard]] constexpr auto unsafe_cast(auto const &src) {
40
+ [[nodiscard]] SAFE_INLINE constexpr auto unsafe_cast(auto const &src) {
41
41
return T{safe::unsafe_cast_ferry{src}};
42
42
}
43
43
44
44
template <typename T>
45
45
requires (!safe::Var<T>)
46
- [[nodiscard]] constexpr auto unsafe_cast(auto const &src) {
46
+ [[nodiscard]] SAFE_INLINE constexpr auto unsafe_cast(auto const &src) {
47
47
return src;
48
48
}
Original file line number Diff line number Diff line change
1
+ #pragma once
2
+
3
+ #include < safe/detail/concepts.hpp>
4
+ #include < safe/detail/fwd.hpp>
5
+ #include < safe/var.hpp>
6
+
7
+ #include < concepts>
8
+
9
+ template <typename To, safe::Var From>
10
+ requires (std::is_convertible_v<typename From::value_type, To>)
11
+ [[nodiscard]] SAFE_INLINE constexpr To safe_cast(From const &src) {
12
+ static_assert (safe::detail::integral_type<To>::requirement >=
13
+ From::requirement,
14
+ " The safe value must fit within the target value type." );
15
+
16
+ return static_cast <To>(src.unsafe_value_ );
17
+ }
Original file line number Diff line number Diff line change 1
1
add_subdirectory (array)
2
2
add_subdirectory (var)
3
+ add_subdirectory (safe_cast)
3
4
4
5
function (add_test_suites)
5
6
foreach (test_file ${ARGN} )
@@ -34,6 +35,7 @@ add_test_suites(
34
35
var.cpp
35
36
match.cpp
36
37
array.cpp
38
+ safe_cast.cpp
37
39
dsl/add.cpp
38
40
dsl/divide.cpp
39
41
dsl/intersection.cpp
Original file line number Diff line number Diff line change
1
+ #include " gmock/gmock.h"
2
+ #include " gtest/gtest.h"
3
+
4
+ #include < cstdint>
5
+ #include < type_traits>
6
+
7
+ #include < safe.hpp>
8
+
9
+ using ::testing::_;
10
+ using ::testing::InSequence;
11
+ using ::testing::Return;
12
+
13
+ using namespace safe ::interval_types;
14
+ using namespace safe ::int_types;
15
+ using namespace safe ::literals;
16
+
17
+ TEST (safe_cast_test, cast_same_type) {
18
+ auto v = safe_cast<std::int32_t >(42_s32);
19
+ EXPECT_EQ (v, 42 );
20
+ static_assert (std::is_same_v<std::int32_t , decltype (v)>);
21
+ }
22
+
23
+ TEST (safe_cast_test, cast_narrower_type) {
24
+ auto v = safe_cast<std::uint8_t >(42_s32);
25
+ EXPECT_EQ (v, 42 );
26
+ static_assert (std::is_same_v<std::uint8_t , decltype (v)>);
27
+ }
28
+
29
+ TEST (safe_cast_test, cast_different_sign) {
30
+ auto v = safe_cast<std::uint32_t >(99_s32);
31
+ EXPECT_EQ (v, 99 );
32
+ static_assert (std::is_same_v<std::uint32_t , decltype (v)>);
33
+ }
Original file line number Diff line number Diff line change
1
+ function (add_fail_tests)
2
+ foreach (name ${ARGN} )
3
+ add_compile_fail_test("${name} .cpp" LIBRARIES safe_arithmetic)
4
+ endforeach ()
5
+ endfunction ()
6
+
7
+ add_fail_tests(
8
+ incompatible_sign_cast
9
+ incompatible_range_cast)
Original file line number Diff line number Diff line change
1
+ #include < cstdint>
2
+
3
+ #include < safe.hpp>
4
+
5
+ using namespace safe ::interval_types;
6
+ using namespace safe ::int_types;
7
+ using namespace safe ::literals;
8
+
9
+ auto main () -> int { auto v = safe_cast<std::uint8_t >(420_u32); }
Original file line number Diff line number Diff line change
1
+ #include < cstdint>
2
+
3
+ #include < safe.hpp>
4
+
5
+ using namespace safe ::interval_types;
6
+ using namespace safe ::int_types;
7
+ using namespace safe ::literals;
8
+
9
+ auto main () -> int { auto v = safe_cast<std::uint32_t >(-99_s32); }
You can’t perform that action at this time.
0 commit comments