Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
cmake-build-*/

# IDE
/.idea
Expand Down
2 changes: 2 additions & 0 deletions src/conversion/conversion.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export module mcpplibs.primitives.conversion;

export import mcpplibs.primitives.conversion.traits;
export import mcpplibs.primitives.conversion.underlying;
export import mcpplibs.primitives.conversion.mixing;
export import mcpplibs.primitives.conversion.primitive;
124 changes: 124 additions & 0 deletions src/conversion/mixing.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
module;

#include <expected>
#include <type_traits>

export module mcpplibs.primitives.conversion.mixing;

import mcpplibs.primitives.conversion.traits;
import mcpplibs.primitives.conversion.underlying;
import mcpplibs.primitives.primitive;
import mcpplibs.primitives.underlying;

namespace mcpplibs::primitives::conversion::details {

template <meta::primitive_type Primitive>
using primitive_value_t =
meta::traits<std::remove_cvref_t<Primitive>>::value_type;

template <meta::primitive_type Dest, underlying_type Src, typename Caster>
constexpr auto cast_to_primitive_value(Src value, Caster caster) noexcept
-> std::remove_cvref_t<Dest> {
using dest_type = std::remove_cvref_t<Dest>;
using dest_value_type = primitive_value_t<dest_type>;

return dest_type{caster.template operator()<dest_value_type>(value)};
}

template <meta::primitive_type Dest, underlying_type Src, typename Caster>
constexpr auto cast_to_primitive_result(Src value, Caster caster)
-> cast_result<std::remove_cvref_t<Dest>> {
using dest_type = std::remove_cvref_t<Dest>;
using dest_value_type = primitive_value_t<dest_type>;

auto const converted = caster.template operator()<dest_value_type>(value);
if (!converted.has_value()) {
return std::unexpected(converted.error());
}

return dest_type{*converted};
}

} // namespace mcpplibs::primitives::conversion::details

export namespace mcpplibs::primitives::conversion {

template <meta::primitive_type Dest, underlying_type Src>
constexpr auto unchecked_cast(Src value) noexcept -> std::remove_cvref_t<Dest> {
return details::cast_to_primitive_value<Dest>(
value, []<underlying_type DestValue, underlying_type SrcValue>(
SrcValue source) {
return conversion::unchecked_cast<DestValue>(source);
});
}

template <underlying_type Dest, meta::primitive_type Src>
constexpr auto unchecked_cast(Src const &value) noexcept -> std::remove_cv_t<Dest> {
return conversion::unchecked_cast<std::remove_cv_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, underlying_type Src>
constexpr auto checked_cast(Src value)
-> cast_result<std::remove_cvref_t<Dest>> {
return details::cast_to_primitive_result<Dest>(
value, []<underlying_type DestValue, underlying_type SrcValue>(
SrcValue source) {
return conversion::checked_cast<DestValue>(source);
});
}

template <underlying_type Dest, meta::primitive_type Src>
constexpr auto checked_cast(Src const &value)
-> cast_result<std::remove_cv_t<Dest>> {
return conversion::checked_cast<std::remove_cv_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, underlying_type Src>
constexpr auto saturating_cast(Src value) noexcept
-> std::remove_cvref_t<Dest> {
return details::cast_to_primitive_value<Dest>(
value, []<underlying_type DestValue, underlying_type SrcValue>(
SrcValue source) {
return conversion::saturating_cast<DestValue>(source);
});
}

template <underlying_type Dest, meta::primitive_type Src>
constexpr auto saturating_cast(Src const &value) noexcept
-> std::remove_cv_t<Dest> {
return conversion::saturating_cast<std::remove_cv_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, underlying_type Src>
constexpr auto truncating_cast(Src value) noexcept
-> std::remove_cvref_t<Dest> {
return details::cast_to_primitive_value<Dest>(
value, []<underlying_type DestValue, underlying_type SrcValue>(
SrcValue source) {
return conversion::truncating_cast<DestValue>(source);
});
}

template <underlying_type Dest, meta::primitive_type Src>
constexpr auto truncating_cast(Src const &value) noexcept
-> std::remove_cv_t<Dest> {
return conversion::truncating_cast<std::remove_cv_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, underlying_type Src>
constexpr auto exact_cast(Src value)
-> cast_result<std::remove_cvref_t<Dest>> {
return details::cast_to_primitive_result<Dest>(
value, []<underlying_type DestValue, underlying_type SrcValue>(
SrcValue source) {
return conversion::exact_cast<DestValue>(source);
});
}

template <underlying_type Dest, meta::primitive_type Src>
constexpr auto exact_cast(Src const &value)
-> cast_result<std::remove_cv_t<Dest>> {
return conversion::exact_cast<std::remove_cv_t<Dest>>(value.load());
}

} // namespace mcpplibs::primitives::conversion
43 changes: 43 additions & 0 deletions src/conversion/primitive.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module;

#include <type_traits>

export module mcpplibs.primitives.conversion.primitive;

import mcpplibs.primitives.conversion.traits;
import mcpplibs.primitives.conversion.mixing;
import mcpplibs.primitives.primitive;

export namespace mcpplibs::primitives::conversion {

template <meta::primitive_type Dest, meta::primitive_type Src>
constexpr auto unchecked_cast(Src const &value) noexcept
-> std::remove_cvref_t<Dest> {
return conversion::unchecked_cast<std::remove_cvref_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, meta::primitive_type Src>
constexpr auto checked_cast(Src const &value)
-> cast_result<std::remove_cvref_t<Dest>> {
return conversion::checked_cast<std::remove_cvref_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, meta::primitive_type Src>
constexpr auto saturating_cast(Src const &value) noexcept
-> std::remove_cvref_t<Dest> {
return conversion::saturating_cast<std::remove_cvref_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, meta::primitive_type Src>
constexpr auto truncating_cast(Src const &value) noexcept
-> std::remove_cvref_t<Dest> {
return conversion::truncating_cast<std::remove_cvref_t<Dest>>(value.load());
}

template <meta::primitive_type Dest, meta::primitive_type Src>
constexpr auto exact_cast(Src const &value)
-> cast_result<std::remove_cvref_t<Dest>> {
return conversion::exact_cast<std::remove_cvref_t<Dest>>(value.load());
}

} // namespace mcpplibs::primitives::conversion
Loading
Loading