Commit 32cdc1f7 authored by Quentin Khan's avatar Quentin Khan

FKernelConcepts: SFINAE classes to check kernel capacities

The adaptive algorithm have been updated to use them.
parent 652a8070
......@@ -12,9 +12,19 @@
#include "Containers/FTreeCoordinate.hpp"
#include "Utils/FAlgorithmTimers.hpp"
template<class _Tree, class _Kernel>
#include "Kernels/FKernelConcepts.hpp"
template<class _Tree, class _Kernel,
typename std::enable_if < true
&& scalfmm::sfinae::has_P2M<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2M<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2L<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_L2L<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_L2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_P2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_P2L<_Tree, _Kernel>::value
> ::type* = nullptr >
class FAdaptiveSequential : public FAlgorithmInterface, public FAlgorithmTimers {
public:
using tree_t = _Tree;
......
......@@ -21,7 +21,19 @@
#include "Containers/FTreeCoordinate.hpp"
#include "Utils/FAlgorithmTimers.hpp"
template<class _Tree, class _Kernel>
#include "Kernels/FKernelConcepts.hpp"
template<class _Tree, class _Kernel,
typename std::enable_if < true
&& scalfmm::sfinae::has_P2M<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2M<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2L<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_L2L<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_L2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_partial_P2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_M2P<_Tree, _Kernel>::value
&& scalfmm::sfinae::has_P2L<_Tree, _Kernel>::value
> ::type* = nullptr >
class FAdaptiveTask : public FAlgorithmInterface, public FAlgorithmTimers {
public:
using tree_t = _Tree;
......
#ifndef FKERNEL_CONCEPTS_HPP
#define FKERNEL_CONCEPTS_HPP
#include <type_traits>
#include "Containers/FTreeCoordinate.hpp"
namespace scalfmm {
namespace sfinae {
namespace details {
#ifdef declare_has_method
#error declare_has_method macro is already defined... This needs fixing.
#endif
#define declare_has_method(name) \
template<typename K, typename Ret, typename ... Args> \
struct has_##name { \
template<typename...> using void_t = void; \
template<typename k, typename = void_t<> > \
struct check : std::false_type {}; \
template<typename k> \
struct check<k, void_t<decltype(std::declval<k>(). name(std::declval<Args>()...))> > \
: std::true_type {}; \
constexpr static const bool value = check<K>::value; \
};
declare_has_method(P2M);
declare_has_method(P2L);
declare_has_method(M2M);
declare_has_method(M2P);
declare_has_method(M2L);
declare_has_method(L2L);
declare_has_method(L2P);
declare_has_method(P2P);
#undef declare_has_method
}
template<typename Tree, typename Kernel>
struct has_M2P {
enum : bool {
value =
details::has_M2P<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::particle_container_t*
>::value
};
};
template<typename Tree, typename Kernel>
struct has_P2L {
enum : bool {
value =
details::has_P2L<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::particle_container_t*
>::value
};
};
template<typename Tree, typename Kernel>
struct has_P2M {
enum : bool {
value =
details::has_P2M<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::particle_container_t*
>::value
};
};
template<typename Tree, typename Kernel>
struct has_M2M {
enum : bool {
value =
details::has_M2M<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::data_t**,
int
>::value
};
};
template<typename Tree, typename Kernel>
struct has_M2L {
enum : bool {
value =
details::has_M2L<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::data_t const**,
int*, int, int
>::value
};
};
template<typename Tree, typename Kernel>
struct has_L2L {
enum : bool {
value =
details::has_L2L<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::data_t**,
int
>::value
};
};
template<typename Tree, typename Kernel>
struct has_L2P {
enum : bool {
value =
details::has_L2P<Kernel, void,
typename Tree::node_t::data_t*,
typename Tree::node_t::particle_container_t*
>::value
};
};
template<typename Tree, typename Kernel>
struct has_P2P {
enum : bool {
value =
details::has_P2P<Kernel, void,
FTreeCoordinate,
typename Tree::node_t::particle_container_t*,
typename Tree::node_t::particle_container_t*,
typename Tree::node_t::particle_container_t**,
int*, int
>::value
};
};
template<typename Tree, typename Kernel>
struct has_partial_P2P {
enum : bool {
value =
details::has_P2P<Kernel, void,
FTreeCoordinate,
typename Tree::node_t::particle_container_t*,
typename Tree::node_t::particle_container_t*,
typename Tree::node_t::particle_container_t**,
int*, int, bool
>::value
};
};
}
}
#endif /* FKERNEL_CONCEPTS_HPP */
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