Skip to content

Commit

Permalink
Merge pull request #110 from mapbox/110-get_unchecked
Browse files Browse the repository at this point in the history
Add get_unchecked<type>()
  • Loading branch information
artemp committed Jun 2, 2016
2 parents 37acc5a + 434dab0 commit 20e44ac
Showing 1 changed file with 103 additions and 29 deletions.
132 changes: 103 additions & 29 deletions include/mapbox/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ struct dispatcher<F, V, R, T, Types...>
{
if (v.template is<T>())
{
return f(unwrapper<T>::apply_const(v.template get<T>()));
return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
}
else
{
Expand All @@ -282,7 +282,7 @@ struct dispatcher<F, V, R, T, Types...>
{
if (v.template is<T>())
{
return f(unwrapper<T>::apply(v.template get<T>()));
return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
}
else
{
Expand All @@ -296,12 +296,12 @@ struct dispatcher<F, V, R, T>
{
VARIANT_INLINE static R apply_const(V const& v, F&& f)
{
return f(unwrapper<T>::apply_const(v.template get<T>()));
return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
}

VARIANT_INLINE static R apply(V& v, F&& f)
{
return f(unwrapper<T>::apply(v.template get<T>()));
return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
}
};

Expand All @@ -315,8 +315,8 @@ struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
{
if (rhs.template is<T1>()) // call binary functor
{
return f(unwrapper<T0>::apply_const(lhs.template get<T0>()),
unwrapper<T1>::apply_const(rhs.template get<T1>()));
return f(unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
}
else
{
Expand All @@ -328,8 +328,8 @@ struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
{
if (rhs.template is<T1>()) // call binary functor
{
return f(unwrapper<T0>::apply(lhs.template get<T0>()),
unwrapper<T1>::apply(rhs.template get<T1>()));
return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
}
else
{
Expand All @@ -343,14 +343,14 @@ struct binary_dispatcher_rhs<F, V, R, T0, T1>
{
VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
{
return f(unwrapper<T0>::apply_const(lhs.template get<T0>()),
unwrapper<T1>::apply_const(rhs.template get<T1>()));
return f(unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
}

VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
{
return f(unwrapper<T0>::apply(lhs.template get<T0>()),
unwrapper<T1>::apply(rhs.template get<T1>()));
return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
}
};

Expand All @@ -364,8 +364,8 @@ struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
{
if (lhs.template is<T1>()) // call binary functor
{
return f(unwrapper<T1>::apply_const(lhs.template get<T1>()),
unwrapper<T0>::apply_const(rhs.template get<T0>()));
return f(unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
}
else
{
Expand All @@ -377,8 +377,8 @@ struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
{
if (lhs.template is<T1>()) // call binary functor
{
return f(unwrapper<T1>::apply(lhs.template get<T1>()),
unwrapper<T0>::apply(rhs.template get<T0>()));
return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
}
else
{
Expand All @@ -392,14 +392,14 @@ struct binary_dispatcher_lhs<F, V, R, T0, T1>
{
VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
{
return f(unwrapper<T1>::apply_const(lhs.template get<T1>()),
unwrapper<T0>::apply_const(rhs.template get<T0>()));
return f(unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
}

VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
{
return f(unwrapper<T1>::apply(lhs.template get<T1>()),
unwrapper<T0>::apply(rhs.template get<T0>()));
return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
}
};

Expand All @@ -415,8 +415,8 @@ struct binary_dispatcher<F, V, R, T, Types...>
{
if (v1.template is<T>())
{
return f(unwrapper<T>::apply_const(v0.template get<T>()),
unwrapper<T>::apply_const(v1.template get<T>())); // call binary functor
return f(unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
unwrapper<T>::apply_const(v1.template get_unchecked<T>())); // call binary functor
}
else
{
Expand All @@ -436,8 +436,8 @@ struct binary_dispatcher<F, V, R, T, Types...>
{
if (v1.template is<T>())
{
return f(unwrapper<T>::apply(v0.template get<T>()),
unwrapper<T>::apply(v1.template get<T>())); // call binary functor
return f(unwrapper<T>::apply(v0.template get_unchecked<T>()),
unwrapper<T>::apply(v1.template get_unchecked<T>())); // call binary functor
}
else
{
Expand All @@ -457,14 +457,14 @@ struct binary_dispatcher<F, V, R, T>
{
VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f)
{
return f(unwrapper<T>::apply_const(v0.template get<T>()),
unwrapper<T>::apply_const(v1.template get<T>())); // call binary functor
return f(unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
unwrapper<T>::apply_const(v1.template get_unchecked<T>())); // call binary functor
}

VARIANT_INLINE static R apply(V& v0, V& v1, F&& f)
{
return f(unwrapper<T>::apply(v0.template get<T>()),
unwrapper<T>::apply(v1.template get<T>())); // call binary functor
return f(unwrapper<T>::apply(v0.template get_unchecked<T>()),
unwrapper<T>::apply(v1.template get_unchecked<T>())); // call binary functor
}
};

Expand Down Expand Up @@ -498,7 +498,7 @@ class comparer
template <typename T>
bool operator()(T const& rhs_content) const
{
T const& lhs_content = lhs_.template get<T>();
T const& lhs_content = lhs_.template get_unchecked<T>();
return Comp()(lhs_content, rhs_content);
}

Expand Down Expand Up @@ -652,6 +652,15 @@ class variant
type_index = detail::direct_type<T, Types...>::index;
}

// get_unchecked<T>()
template <typename T, typename std::enable_if<
(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T& get_unchecked()
{
return *reinterpret_cast<T*>(&data);
}

#ifdef __EXCEPTIONS
// get<T>()
template <typename T, typename std::enable_if<
(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
Expand All @@ -666,7 +675,16 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

template <typename T, typename std::enable_if<
(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get_unchecked() const
{
return *reinterpret_cast<T const*>(&data);
}

#ifdef __EXCEPTIONS
template <typename T, typename std::enable_if<
(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get() const
Expand All @@ -680,7 +698,17 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

// get_unchecked<T>() - T stored as recursive_wrapper<T>
template <typename T, typename std::enable_if<
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T& get_unchecked()
{
return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
}

#ifdef __EXCEPTIONS
// get<T>() - T stored as recursive_wrapper<T>
template <typename T, typename std::enable_if<
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
Expand All @@ -695,7 +723,16 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

template <typename T, typename std::enable_if<
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get_unchecked() const
{
return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
}

#ifdef __EXCEPTIONS
template <typename T, typename std::enable_if<
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get() const
Expand All @@ -709,7 +746,17 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

// get_unchecked<T>() - T stored as std::reference_wrapper<T>
template <typename T, typename std::enable_if<
(detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T& get_unchecked()
{
return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
}

#ifdef __EXCEPTIONS
// get<T>() - T stored as std::reference_wrapper<T>
template <typename T, typename std::enable_if<
(detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
Expand All @@ -724,7 +771,16 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

template <typename T, typename std::enable_if<
(detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get_unchecked() const
{
return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get();
}

#ifdef __EXCEPTIONS
template <typename T, typename std::enable_if<
(detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)>::type* = nullptr>
VARIANT_INLINE T const& get() const
Expand All @@ -738,6 +794,7 @@ class variant
throw bad_variant_access("in get<T>()");
}
}
#endif

// This function is deprecated because it returns an internal index field.
// Use which() instead.
Expand Down Expand Up @@ -869,17 +926,34 @@ auto VARIANT_INLINE apply_visitor(F&& f, V& v0, V& v1) -> decltype(V::binary_vis
}

// getter interface

#ifdef __EXCEPTIONS
template <typename ResultType, typename T>
auto get(T& var)->decltype(var.template get<ResultType>())
{
return var.template get<ResultType>();
}
#endif

template <typename ResultType, typename T>
ResultType& get_unchecked(T& var)
{
return var.template get_unchecked<ResultType>();
}

#ifdef __EXCEPTIONS
template <typename ResultType, typename T>
auto get(T const& var)->decltype(var.template get<ResultType>())
{
return var.template get<ResultType>();
}
#endif

template <typename ResultType, typename T>
ResultType const& get_unchecked(T const& var)
{
return var.template get_unchecked<ResultType>();
}
} // namespace util
} // namespace mapbox

Expand Down

0 comments on commit 20e44ac

Please sign in to comment.