Program Listing for File get.hpp
↰ Return to documentation for file (/tmp/ws/src/proxsuite/include/proxsuite/linalg/veg/util/get.hpp
)
#ifndef VEG_GET_HPP_QRS8GNSHS
#define VEG_GET_HPP_QRS8GNSHS
#include "proxsuite/linalg/veg/type_traits/core.hpp"
#include "proxsuite/linalg/veg/internal/prologue.hpp"
namespace proxsuite {
namespace linalg {
namespace veg {
namespace meta {
template<typename T>
struct is_bounded_array : false_type
{};
template<typename T, usize N>
struct is_bounded_array<T[N]> : true_type
{};
template<typename T>
struct array_extent : constant<usize, 0>
{};
template<usize N, typename T>
struct array_extent<T[N]> : constant<usize, N>
{};
} // namespace meta
namespace _detail {
namespace _meta {
template<typename T>
void
get() = delete;
struct array_get
{
template<typename I, typename T>
using result_type = decltype(VEG_DECLVAL(T&&)[I::value]);
template<usize I, typename T>
VEG_INLINE static constexpr auto apply(T&& arr)
VEG_NOEXCEPT->decltype(VEG_FWD(arr)[I])
{
return VEG_FWD(arr)[I];
}
};
struct member_get
{
template<typename I, typename T>
using result_type = decltype(VEG_DECLVAL(T&&).template get<I::value>());
template<usize I, typename T>
VEG_INLINE static constexpr auto apply(T&& arg)
VEG_DEDUCE_RET(VEG_FWD(arg).template get<I>());
};
struct adl_get
{
template<typename I, typename T>
using result_type = decltype(get<I::value>(VEG_DECLVAL(T&&)));
template<usize I, typename T>
VEG_INLINE static constexpr auto apply(T&& arg)
VEG_DEDUCE_RET(get<I>(VEG_FWD(arg)));
};
struct none_found : true_type
{
template<typename I, typename T>
using result_type = void;
};
template<typename I, typename T>
using member_get_expr = decltype(VEG_DECLVAL(T&&).template get<I::value>());
template<typename I, typename T>
using adl_get_expr = decltype(get<I::value>(VEG_DECLVAL(T&&)));
template<usize I, typename T>
struct has_array_get
: meta::bool_constant<meta::is_bounded_array<meta::uncvref_t<T>>::value>
, array_get
{};
template<usize I, typename T>
struct has_member_get
: bool_constant<VEG_CONCEPT(
detected<member_get::result_type, constant<usize, I>, T&&>)>
, member_get
{};
template<usize I, typename T>
struct has_adl_get
: bool_constant<VEG_CONCEPT(
detected<adl_get::result_type, constant<usize, I>, T&&>)>
, adl_get
{};
} // namespace _meta
} // namespace _detail
namespace concepts {
namespace aux {
VEG_DEF_CONCEPT((usize I, usize N), less_than, (I < N));
VEG_DEF_CONCEPT(typename T, bounded_array, meta::is_bounded_array<T>::value);
} // namespace aux
VEG_DEF_CONCEPT_CONJUNCTION(
(usize I, typename T),
array_gettable,
((aux::, bounded_array<uncvref_t<T>>),
(aux::, less_than<I, meta::array_extent<uncvref_t<T>>::value>)));
VEG_DEF_CONCEPT(
(usize I, typename T),
member_gettable,
VEG_CONCEPT(
detected<_detail::_meta::member_get_expr, meta::constant<usize, I>, T>));
VEG_DEF_CONCEPT(
(usize I, typename T),
adl_gettable,
VEG_CONCEPT(
detected<_detail::_meta::adl_get_expr, meta::constant<usize, I>, T>));
VEG_DEF_CONCEPT_DISJUNCTION((usize I, typename T),
gettable,
((, array_gettable<I, T>),
(, member_gettable<I, T>),
(, adl_gettable<I, T>)));
} // namespace concepts
namespace nb {
template<usize I>
struct get
{
VEG_TEMPLATE(
(typename T,
typename Impl = meta::disjunction<_detail::_meta::has_array_get<I, T>,
_detail::_meta::has_member_get<I, T>,
_detail::_meta::has_adl_get<I, T>,
_detail::_meta::none_found>),
requires(VEG_CONCEPT(gettable<I, T>)),
VEG_INLINE constexpr auto
operator(),
(arg, T&&))
const VEG_NOEXCEPT_IF(VEG_IS_NOEXCEPT(Impl::template apply<I>(VEG_FWD(arg))))
->meta::detected_t<Impl::template result_type, meta::constant<usize, I>, T>
{
return Impl::template apply<I>(VEG_FWD(arg));
}
};
} // namespace nb
VEG_NIEBLOID_TEMPLATE(usize I, get, I);
} // namespace veg
} // namespace linalg
} // namespace proxsuite
#include "proxsuite/linalg/veg/internal/epilogue.hpp"
#endif /* end of include guard VEG_GET_HPP_QRS8GNSHS */