Commit d5e0477d authored by Dominik Charousset's avatar Dominik Charousset

Support immutable sum types

parent ac6b8041
...@@ -36,6 +36,8 @@ struct default_sum_type_access { ...@@ -36,6 +36,8 @@ struct default_sum_type_access {
static constexpr bool specialized = true; static constexpr bool specialized = true;
static constexpr bool is_mutable = true;
template <int Pos> template <int Pos>
static bool is(const T& x, std::integral_constant<int, Pos> token) { static bool is(const T& x, std::integral_constant<int, Pos> token) {
return x.get_data().is(token); return x.get_data().is(token);
......
...@@ -31,6 +31,13 @@ constexpr bool SumType() { ...@@ -31,6 +31,13 @@ constexpr bool SumType() {
return has_sum_type_access<typename std::decay<T>::type>::value; return has_sum_type_access<typename std::decay<T>::type>::value;
} }
/// Concept for checking whether `T` supports the sum type API by specializing
/// `sum_type_access` and grants non-const element access.
template <class T>
constexpr bool MutableSumType() {
return has_mutable_sum_type_access<typename std::decay<T>::type>::value;
}
/// Concept for checking whether all `Ts` support the sum type API by /// Concept for checking whether all `Ts` support the sum type API by
/// specializing `sum_type_access`. /// specializing `sum_type_access`.
template <class... Ts> template <class... Ts>
...@@ -44,7 +51,7 @@ constexpr bool SumTypes() { ...@@ -44,7 +51,7 @@ constexpr bool SumTypes() {
/// @pre `holds_alternative<T>(x)` /// @pre `holds_alternative<T>(x)`
/// @relates SumType /// @relates SumType
template <class T, class U> template <class T, class U>
detail::enable_if_t<SumType<U>(), T&> get(U& x) { detail::enable_if_t<MutableSumType<U>(), T&> get(U& x) {
using namespace detail; using namespace detail;
using trait = sum_type_access<U>; using trait = sum_type_access<U>;
int_token<tl_index_where<typename trait::types, int_token<tl_index_where<typename trait::types,
...@@ -72,7 +79,7 @@ detail::enable_if_t<SumType<U>(), const T&> get(const U& x) { ...@@ -72,7 +79,7 @@ detail::enable_if_t<SumType<U>(), const T&> get(const U& x) {
/// `nullptr` otherwise. /// `nullptr` otherwise.
/// @relates SumType /// @relates SumType
template <class T, class U> template <class T, class U>
detail::enable_if_t<SumType<U>(), T*> get_if(U* x) { detail::enable_if_t<MutableSumType<U>(), T*> get_if(U* x) {
using namespace detail; using namespace detail;
using trait = sum_type_access<U>; using trait = sum_type_access<U>;
int_token<tl_index_where<typename trait::types, int_token<tl_index_where<typename trait::types,
......
...@@ -28,13 +28,23 @@ namespace caf { ...@@ -28,13 +28,23 @@ namespace caf {
template <class T> template <class T>
struct sum_type_access { struct sum_type_access {
static constexpr bool specialized = false; static constexpr bool specialized = false;
static constexpr bool is_mutable = false;
}; };
/// Evaluates to `true` if `T` specializes `sum_type_access` /// Evaluates to `true` if `T` specializes `sum_type_access`.
/// @relates SumType /// @relates SumType
template <class T> template <class T>
struct has_sum_type_access { struct has_sum_type_access {
static constexpr bool value = sum_type_access<T>::specialized; static constexpr bool value = sum_type_access<T>::specialized;
}; };
/// Evaluates to `true` if `T` specializes `sum_type_access` and allows
/// non-const element access.
/// @relates SumType
template <class T>
struct has_mutable_sum_type_access {
static constexpr bool value = sum_type_access<T>::specialized
&& sum_type_access<T>::is_mutable;
};
} // namespace caf } // namespace caf
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment