/*+ ARES/HADES/BORG Package -- ./libLSS/tools/array_concepts.hpp Copyright (C) 2014-2020 Guilhem Lavaux Copyright (C) 2009-2020 Jens Jasche Additional contributions from: Guilhem Lavaux (2023) +*/ #ifndef __LIBLSS_TOOLS_ARRAYCONCEPTS_HPP #define __LIBLSS_TOOLS_ARRAYCONCEPTS_HPP #include #include #include #include #include #include #include #include namespace LibLSS { namespace array_concepts { BOOST_TTI_HAS_TYPE(element); template struct has_shape_info : std::false_type {}; template struct has_shape_info : std::true_type {}; template struct is_callable { template static auto test(U *p) -> decltype((*p)(std::declval()...), void(), std::true_type()); template static auto test(...) -> decltype(std::false_type()); static constexpr bool value = decltype(test(0))::value; }; // https://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions/8752988 #define MEMBER_FUNC_CHECKER(name, fn, args) \ template \ struct name : std::false_type {}; \ template \ struct name< \ C, ret, \ typename std::enable_if().fn args), ret>::value>::type> \ : std::true_type {}; MEMBER_FUNC_CHECKER(has_member_function_data, data, ()) MEMBER_FUNC_CHECKER(has_member_function_origin, origin, ()) MEMBER_FUNC_CHECKER(has_member_function_reindex, reindex, (0)) template using is_array_like = has_type_element; template struct check_element_type { typedef void element; }; template struct check_element_type< C, typename std::enable_if::value>::type> { typedef typename C::element element; }; template struct is_complex_type : std::false_type {}; template struct is_complex_type> : std::true_type {}; template using is_array_storage = boost::mpl::and_< has_type_element, has_member_function_data::element *>>; template using is_array_sub = boost::mpl::and_< has_type_element, has_member_function_origin< T, typename check_element_type::element *>>; template using is_array_view = boost::mpl::and_< has_type_element, boost::mpl::not_::element *>>, has_member_function_reindex>; } // namespace array_concepts } // namespace LibLSS #endif